【问题标题】:Understanding the impact of var and val with respect to getters and setters of a property了解 var 和 val 对属性的 getter 和 setter 的影响
【发布时间】:2021-11-03 22:22:49
【问题描述】:

假设我有一个 Kotlin 类 Dog 有两个属性 weightweightInKgs

class Dog(val weight: Double) {  
    // property without initializing works. Why?
    val weightinKgs: Double
    get() = weight/ 2.2;
}

上面的代码运行没有错误。我知道 Kotlin 中的每个属性都必须初始化,那么为什么在不初始化属性的情况下定义 getter 呢?其次,当val 更改为varweightInKgs 时,会产生一个要求初始化的错误。将其更改为var 会如何破坏代码?

class Dog(val weight: Double) {
    // well its doesn't work now. 
    var weightinKgs: Double
        get() = weight/ 2.2;
}

【问题讨论】:

    标签: kotlin oop


    【解决方案1】:

    每个属性都有一个支持字段必须被初始化。如果以下任何一项为真,则属性具有支持字段:

    • 您在声明站点使用= 初始化支持字段。
    • 它有一个引用 field 的自定义 getter 或 setter。
    • 它使用隐式getter或setter,隐式使用field

    否则,它没有支持字段。

    如果 getter 和/或 setter 没有使用支持字段,则无需初始化。您的第一个代码块有一个不使用 field 的自定义 getter。

    在您的第二个代码块中,您有一个 var,它使用隐式 setter,它使用支持字段,因此必须初始化支持字段。

    【讨论】:

      【解决方案2】:

      如果不是很明显,get() 是一个函数,它会在您每次调用它时计算一个值 (weight / 2.2)。基本上相当于这个

      fun getWeightInKgs(): Double {
          return weight / 2.2
      }
      

      所以这就是它没有支持字段的原因,它实际上并没有存储值。但是 Kotlin 将这些类型的 getX() 函数(以及 setis 等)呈现为属性,并鼓励您使用属性访问语法,因此使用 dog.weightInKgs 而不是 dog.getWeightInKgs()。有点隐藏具体的实现细节

      如果你不想每次都计算重量,只想计算一次,那么你就这样做

      val weightInKgs = weight / 2.2
      

      然后它有一个支持字段,因为该值必须存储在某个地方。你也可以有一个 getter 函数来引用私有 valvar 并返回它的值,而不是 giving the property itself a backing field,但如果你需要做那种事情,你可能会明白为什么你将!这通常是因为当你的 getter 和/或 setter 做一些比隐藏或验证内部数据值更复杂的事情时

      【讨论】:

        猜你喜欢
        • 2017-02-24
        • 2018-12-08
        • 2019-11-21
        • 1970-01-01
        • 1970-01-01
        • 2018-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多