Kotlin val 差异 getter 重写与赋值

Kotlin val difference getter override vs assignment

我开始玩弄 Kotlin 并阅读了一些关于自定义可变 val 的内容 getter。如 here or in the Kotlin Coding Convention 中所述,如果结果可以更改,则不应覆盖 getter。

class SampleArray(val size: Int) {
    val isEmpty get() = size == 0  // size is set at the beginning and does not change so this is ok
}

class SampleArray(var size: Int) {
    fun isEmpty() { return size == 0 }  // size is set at the beginning but can also change over time so function is prefered
}

但仅从指南中的用法角度来看,以下两者之间的区别在哪里

class SampleArray(val size: Int) {
    val isEmpty get() = size == 0  // size can not change so this can be used instad of function
    val isEmpty = size == 0        // isEmpty is assigned at the beginning ad will keep this value also if size could change
}

的回答我可以看到 getter 重写值未存储。 getter 重写是否与赋值不同?也许与代表或 latinit?

这里的主要区别在于,在 val isEmpty get() = ... 中,每次访问 属性 时都会计算主体,而在 val isEmpty = ... 中,右侧的表达式在对象构造,结果存储在 the backing field 中,每次使用 属性 时都会返回这个准确的结果。

因此,第一种方法适用于希望每次都计算结果的情况,而第二种方法适用于希望结果只计算一次并存储的情况。

在您的第二个示例中,size 是不可变值,因此两种方式均有效。

然而,具有覆盖 getter get() = size == 0 has no backing field 的变体因此每次访问 isEmpty 变量时都会评估 size == 0

另一方面,当使用初始化器 = size == 0 时,表达式 size == 0 在构造期间被评估(检查确切的时间和方式 - An in-depth look at Kotlin’s initializers) and stored to the backing field,然后在您访问变量。