kotlin ...ArrayOf 作用域问题

kotlin ...ArrayOf scoping issues

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

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)
    }
}


失败并显示消息 "unresolved reference CORRECT_BUZZ_PATTERN"

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

主要区别在于,在第一种情况下,CORRECT_BUZZ_PATTERN 是在 class 之外定义的,并被视为 read-only 变量(可通过其 getter 访问),而在第二个片段中,它是一个 read-only 实例变量 ,因此它不能用作常量。 但是,此代码可以工作:

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 {
    ...
}

所以CORRECT_BUZZ_PATTERN是属于classMainKtstatic final数组,可以通过getter.

访问

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

public final class TestLongArrayOf {
    private final long[] CORRECT_BUZZ_PATTERN

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

public final enum TestLongArrayOf$BuzzType { 
    ...
}

请注意,在这种情况下 CORRECT_BUZZ_PATTERN 是一个实例变量,可以通过其 getter 检索。但是,由于它是一个实例变量,您必须在 TestLongArrayOf 的实例上调用 getter,这就是为什么我的答案顶部的代码片段有效。