我开始和Kotlin一起玩,并通过自定义getter阅读有关可变val的内容。正如here或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
}
从this回答我可以看到,对于getter覆盖,不会存储该值。还有其他东西,其中getter覆盖与赋值不同吗?也许与代表或latinit?
答案 0 :(得分:8)
在您的第二个示例中,size
是不可变值,因此两种方式都有效。
每次访问get() = size == 0
变量时,都会评估带有重写的getter size == 0
has no backing field并因此isEmpty
的变体。
另一方面,当使用初始化程序= size == 0
时,在构造期间评估表达式size == 0
(确切地检查何时以及如何 - An in-depth look at Kotlin’s initializers)并存储到backing field ,当访问变量时返回的值。
答案 1 :(得分:6)
这里的关键区别在于,val isEmpty get() = ...
每次访问属性时都会对主体进行求值,而在val isEmpty = ...
中,在对象构造期间对右侧的表达式进行求值,结果为:存储在the backing field中,每次使用该属性时都会返回此确切结果。
因此,当您希望每次计算结果时,第一种方法是合适的,而当您希望结果只计算一次并存储时,第二种方法是好的。