Kotlin val差异吸气器覆盖与分配

时间:2017-08-01 09:09:44

标签: kotlin getter

我开始和Kotlin一起玩,并通过自定义getter阅读有关可变val的内容。正如hereKotlin 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?

2 个答案:

答案 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中,每次使用该属性时都会返回此确切结果。

因此,当您希望每次计算结果时,第一种方法是合适的,而当您希望结果只计算一次并存储时,第二种方法是好的。