这些是等价的吗?
val foo = someFooReturningFunction()
val foo get() = someFooReturningFunction()
我理解它们的文档的方式,但在我自己的测试中,它们不是。
每次访问属性时都会使用 get() someFooReturningFunction()
进行评估,而不会仅评估一次。
答案 0 :(得分:7)
它们并不等同。确实对每个属性访问进行了自定义getter的评估,类似于普通函数,而没有自定义访问器的val
属性仅在初始化时被评估一次(并且实际存储在JVM上的final
字段中平台)。
以下是至少一些差异:
如果属性具有自定义getter(或open
,因此可能会被自定义getter覆盖),则控制流分析和可空性推理会将其考虑在内,因为没有保证该属性在后续调用中返回相同的值:
if (someObject.defaultGetterProperty != null) {
someObject.defaultGetterProperty.let { println(it) } // OK
}
if (someObject.propertyWithCustomGetter != null) {
someObject.propertyWithCustomGetter { println(it) } // Error: cannot smart-cast
}
当属性为private
时,如果它没有自定义getter,则根本不会生成getter,直接访问后备字段。然而,这是一个实现细节,而不是可依赖的东西。
答案 1 :(得分:1)
没有。除了@ hotkey的原因,这里还有一个简单的演示,使用可变属性显示它们肯定不相同的时候。 TLDR:如果您的属性是使用mutable属性计算的,请始终在初始化程序上使用自定义getter。
data class Calculation(val value1: Int, var value2: Int) {
val sum: Int = value1 + value2
val sumWithGetter: Int
get() = value1 + value2
}
val calculation = Calculation(1, 2)
println(calculation.sumWithGetter) // prints 3
println(calculation.sum) // prints 3
calculation.value2 = 0
println(calculation.sumWithGetter) // prints 1 (correct)
println(calculation.sum) // prints 3!