假设我有一个 Kotlin 类 Dog
,有两个属性 weight
和 weightInKgs
class Dog(val weight: Double) {
// property without initializing works. Why?
val weightinKgs: Double
get() = weight/ 2.2;
}
上面的代码运行没有错误。我知道 Kotlin 中的每个属性都必须初始化,那么为什么在不初始化属性的情况下定义一个 getter 呢?其次,当 val
为 var
更改为 weightInKgs
时,会产生一个要求初始化的错误。将其更改为 var
会如何破坏代码?
class Dog(val weight: Double) {
// well its doesn't work now.
var weightinKgs: Double
get() = weight/ 2.2;
}
答案 0 :(得分:2)
每个带有支持字段的属性都必须初始化。如果您定义了一个不使用支持字段的自定义 getter,并且不在声明站点使用 =
为支持字段分配值,那么它没有一个值,因此没有什么可初始化。
如果您将属性定义为 var
而不定义不使用支持字段的自定义 setter,那么它再次具有您必须初始化的支持字段(因为隐式 setter 使用了一个)。< /p>
答案 1 :(得分:0)
如果不是很明显,get()
是每次调用时都会计算一个值 (weight / 2.2
) 的函数。基本上相当于这个
fun getWeightInKgs(): Double {
return weight / 2.2
}
所以这就是它没有支持字段的原因,它实际上并不存储值。但是 Kotlin 将这些类型的 getX()
函数(以及 set
、is
等)呈现为属性,并鼓励您使用属性访问语法,因此 dog.weightInKgs
而不是 {{1 }}。有点隐藏了具体的实现细节
如果你不想每次都计算重量,只想做一次,那你就做
dog.getWeightInKgs()
然后它将有一个支持字段,因为该值必须存储在某个地方。你也可以有一个 getter 函数来引用一个私有的 val weightInKgs = weight / 2.2
或 val
并返回它的值,而不是 giving the property itself a backing field,但是如果你需要做那种事情,你可能会明白你为什么会这样!这通常是因为当您的 getter 和/或 setter 正在做一些比隐藏或验证内部数据值更复杂的事情时