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,然后在您访问变量。
我开始玩弄 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
}
从
这里的主要区别在于,在 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,然后在您访问变量。