Kotlin 只读属性,带和不带 getter
Posted
技术标签:
【中文标题】Kotlin 只读属性,带和不带 getter【英文标题】:Kotlin read only property with and without getter 【发布时间】:2021-11-11 00:46:24 【问题描述】:这些是等价的吗?
val foo = someFooReturningFunction()
val foo get() = someFooReturningFunction()
我理解文档的方式是,但在我自己的测试中它们不是。
使用 get() someFooReturningFunction()
会在每次访问属性时进行评估,否则只会评估一次。
【问题讨论】:
【参考方案1】:它们不等价。自定义 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,直接访问支持字段。然而,这是一个实现细节,不能依赖。
【讨论】:
【参考方案2】:没有。除了@hotkey 的原因,这里有一个使用可变属性的简单演示,显示它们何时绝对不等价。 TLDR:如果您的属性是使用可变属性计算的,请始终在初始化程序上使用自定义 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!
【讨论】:
以上是关于Kotlin 只读属性,带和不带 getter的主要内容,如果未能解决你的问题,请参考以下文章