kotlin…范围界定问题列表

kotlin…范围界定问题列表,kotlin,scoping,Kotlin,Scoping,为什么下面的第一个代码示例可以编译,但第二个失败。唯一的变化是我将涉及的val从文件范围移动到了类范围。longArrayOf(…)创建了一个LongArray,对吗? 编译没有问题: val CORRECT_BUZZ_PATTERN = longArrayOf(100, 100, 100, 100, 100, 100) class TestLongArrayOf { enum class BuzzType(val pattern: LongArray) { CORREC

为什么下面的第一个代码示例可以编译,但第二个失败。唯一的变化是我将涉及的val从文件范围移动到了类范围。

longArrayOf(…)创建了一个LongArray,对吗?

编译没有问题:

val CORRECT_BUZZ_PATTERN = longArrayOf(100, 100, 100, 100, 100, 100)
class TestLongArrayOf {
    enum class BuzzType(val pattern: LongArray) {
        CORRECT(CORRECT_BUZZ_PATTERN)
    }
}

失败,并显示消息“未解析的引用正确\u BUZZ\u模式”


主要区别在于,在第一种情况下,
CORRECT\u BUZZ\u PATTERN
在类外定义,并被视为只读变量(通过其getter访问),而在第二种情况下,它是只读的实例变量,因此不能用作常量。 但是,此代码将起作用:

class TestLongArrayOf {
    val CORRECT_BUZZ_PATTERN = longArrayOf(100, 100, 100, 100, 100, 100)
    enum class BuzzType(val pattern: LongArray) {
        CORRECT(TestLongArrayOf().CORRECT_BUZZ_PATTERN)
    }
}
让我们看看生成的字节码。在第一种情况下,您有:

public final class MainKt {
    private final static long[] CORRECT_BUZZ_PATTERN
    public final static long[] getCORRECT_BUZZ_PATTERN() {
        ...
    }
    static {
        // initialize CORRECT_BUZZ_PATTERN here
        ...
    }
}

public final enum TestLongArrayOf$BuzzType {
    ...
}
因此,正确的_BUZZ_模式是属于类
MainKt
静态final
数组,可以通过其getter访问该数组

在第二种情况下,您得到的是:

public final class TestLongArrayOf {
    private final long[] CORRECT_BUZZ_PATTERN

    public final long[] getCORRECT_BUZZ_PATTERN() {
        ...
    }
}

public final enum TestLongArrayOf$BuzzType { 
    ...
}

请注意,在本例中,
CORRECT\u BUZZ\u PATTERN
是一个实例变量,可以通过其getter进行检索。但是,由于它是一个实例变量,您必须在
testlongarayof
的实例上调用getter,这就是为什么我的答案顶部的代码段可以工作的原因。

非常好的解释——特别是kotlin->bytecode的使用。非常感谢。非常感谢。您可以使用IntelliJ IDEA中的
Show Kotlin bytecode
轻松检查字节码
public final class TestLongArrayOf {
    private final long[] CORRECT_BUZZ_PATTERN

    public final long[] getCORRECT_BUZZ_PATTERN() {
        ...
    }
}

public final enum TestLongArrayOf$BuzzType { 
    ...
}