Почему я не могу ссылаться на вложенный объект из 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
.