【问题标题】:Kotlin: why do I need to initialize a var with custom getter?Kotlin:为什么我需要用自定义 getter 初始化一个 var?
【发布时间】:2017-01-03 09:56:44
【问题描述】:

为什么我需要使用返回常量的自定义 getter 来初始化 var

var greeting: String // Property must be initialized 
get() = "hello"

当我将greeting设为只读(val)时,我不需要初始化

【问题讨论】:

  • 那你为什么不把它变成val呢?每个具有支持字段的可变属性都需要初始化。
  • @miensol 同意,这应该是val。我自己也很困惑;混淆的根源在于将val/var 的区别视为常量与变量,而不是只读与可变。

标签: kotlin


【解决方案1】:

这背后的原因是Backing field。当您使用不使用字段标识符访问其值的自定义 getter 创建 val 时,不会生成支持字段。

val greeting: String
    get() = "hello"

如果这样做,则生成支持字段并需要初始化。

val greeting: String // Property must be initialized
    get() = field

现在使用 var。由于后台文件是默认生成的,所以必须初始化。

var greeting: String // Property must be initialized
    get() = "hello"

为了使 var 无需初始化即可使用,您必须提供自定义设置器以防止生成支持字段。例如:

var storage: String = ""
var greeting: String
    get() = "hello"
    set(value) { storage = value}

【讨论】:

  • 初始化是什么意思?提供二传手?或在声明期间提供价值?你能确认一下吗?
  • 提供一个值。通过显式初始化程序或在 init 块内。
  • 如果我在声明或初始化块期间没有提供任何值。为什么需要同时编写 getter 和 setter?我的意思是假设我只是写了 set 块。 var good : Int set(value){ field = 3 } 它仍然会显示有关初始化的错误。但是一旦我写了get() = 3 或其他东西,它就会解决错误。背后的原因是什么?
  • var good : Int set(value){ field = 3 } get() = 3 不工作不知道为什么。但是当我删除 field=3 它工作正常初始化错误消失了。
  • 与上面的答案相同。查看支持字段文档的链接。如果您使用默认的 get/set 或者您在自定义字段中引用字段,则 Var 会生成支持字段。如果生成了支持字段,则需要对其进行初始化。
【解决方案2】:

你的代码没有自定义setter,所以相当于:

var greeting: String
    get() = "hello"
    set(v) {field = v}  // Generated by default

set 的默认实现使用field,所以你必须初始化它。

按照相同的逻辑,如果您的 setget 都使用它(这意味着它们都是自定义的),则不必初始化该字段:

var greeting: String  // no `field` associated!
    get() = "hello"
    set(v) = TODO()

【讨论】:

  • 如果不需要setter,应该是val属性。
  • 如果在定义 getset 时遇到此错误,请确保您没有在任何这些函数中使用 field 引用(如上例中的设置器) .从实现中删除 field 将删除错误。
猜你喜欢
  • 2022-12-15
  • 1970-01-01
  • 2019-06-13
  • 2014-12-26
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多