Почему я не могу ссылаться на вложенный объект из val или typealias, ссылающихся на объект?

Рассмотрим следующий код:

object SomeObjectA {
    object SomeObjectB {
        val a = "test"
    }
}

val X = SomeObjectA
typealias Y = SomeObjectA

SomeObjectA.SomeObjectB // works
X.SomeObjectB // error
Y.SomeObjectB // error

Я не могу ссылаться на вложенный объект (во внешнем объекте), используя val или typealias, которые относятся к внешнему объекту. Почему?

Ответы

Ответ 1

То, что вы описали, происходит потому, что SomeObjectA в вашем примере одновременно является именем объекта и именем его класса.

Чтобы получить доступ к SomeObjectB, вам нужно использовать синтаксис <classname>.<classname>. Вот почему X.SomeObjectB не компилируется (<object>.<classname> не поддерживается)

P.S. Это не объясняет вашу вторую проблему с помощью typealias. Это похоже на ошибку, но я не уверен.

Ответ 2

ошибка компилятора исходит из java, а kotlin object преобразуется в java class es, как показано ниже:

public final class SomeObjectA {
    private SomeObjectA() {/**/}

    public static final SomeObjectA INSTANCE = new SomeObjectA();

    public static final class SomeObjectB {
        private SomeObjectB() {/**/}

        public static final SomeObjectB INSTANCE = new SomeObjectB();
    }
}

SomeObjectA.SomeObjectB скомпилирован в java-код, как показано ниже:

SomeObjectA.SomeObjectB.INSTANCE;

SomeObjectA скомпилирован в java-код, как показано ниже:

SomeObjectA.INSTANCE

мы знаем, что kotlin является базой для java, а java не разрешает доступ к вложенным классам через ссылку на экземпляр, если вы сделаете компилятор, сообщит об ошибке: " Ошибка: java: требуется неожиданный тип: класс, пакет found: variable", например:

SomeObjectA a = SomeObjectA.INSTANCE;
SomeObjectB b = a.SomeObjectB.INSTANCE;// error 
             // ^--- compiler don't know where to go? package&class or variable?   

приведенный ниже код, компилятор kotlin преобразует ошибку компилятора java как: " Ошибка: Kotlin: вложенный объект" SomeObjectB "доступен через ссылку экземпляра".

val a = SomeObjectA;
val b = a.SomeObjectB;
//        ^--- Error

Алиасы типа не вводят новые типы. Они эквивалентны соответствующим базовым типам.

поэтому два утверждения ниже:

 val a = SomeObjectA;
 typealias a2 = SomeObjectA;

избегая использования typealias, вызывающего ненужную ошибку компилятора, kotlin не включает все вложенные классы в typealias.