为啥我不能从引用对象的 val 或 typealias 引用嵌套对象?

Posted

技术标签:

【中文标题】为啥我不能从引用对象的 val 或 typealias 引用嵌套对象?【英文标题】:Why I cannot refer to a nested object from val or typealias referring to an object?为什么我不能从引用对象的 val 或 typealias 引用嵌套对象? 【发布时间】:2017-06-09 10:22:58 【问题描述】:

考虑以下代码:

object SomeObjectA 
    object SomeObjectB 
        val a = "test"
    


val X = SomeObjectA
typealias Y = SomeObjectA

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

我不能使用引用外部对象的valtypealias 来引用嵌套对象(在外部对象中)。为什么?

【问题讨论】:

类似问题:youtrack.jetbrains.com/issue/KT-12632 刚遇到Y.SomeObjectB同样的事情,报告为KT-24902,因为其他问题类似,但并不完全相同。 【参考方案1】:

您所描述的发生是因为您的示例中的SomeObjectA 同时是一个对象的名称​​和它的类的名称。

所以要访问SomeObjectB,您需要使用<classname>.<classname> 语法。这就是X.SomeObjectB 无法编译的原因(<object>.<classname> 不受支持)

附:这并不能真正解释typealias 的第二个问题。对我来说它看起来像一个错误,但我不确定。

【讨论】:

【参考方案2】:

编译器错误来自java,kotlinobjects转换成javaclasses如下:

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不允许通过实例引用访问嵌套类,如果这样做编译器会报错:“Error: java: unexpected type required: class,package发现:变量”,例如:

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

以下代码,kotlin 编译器会将 java 编译器错误转换为:“Error: Kotlin: Nested object 'SomeObjectB' access via instance reference”。

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

类型别名不会引入新类型。它们等价于相应的底层类型。

所以下面的两个语句是相等的:

 val a = SomeObjectA;
 typealias a2 = SomeObjectA;

为了避免使用typealias 导致不必要的编译器错误,kotlin 不包含typealias 中的所有嵌套类。

【讨论】:

以上是关于为啥我不能从引用对象的 val 或 typealias 引用嵌套对象?的主要内容,如果未能解决你的问题,请参考以下文章

为啥使用jQuery时不能通过window对象访问对象?

为啥我的 std::ref 不能按预期工作?

为啥非常量引用不能绑定到临时对象?

在java中,引用数据不就是一种对象么?为啥在调用函数中不能进行修改数值??

为啥我不能将 const 左值引用绑定到返回 T&& 的函数?

为啥我不能引用我的类库?