Kotlin:为什么我需要使用自定义getter初始化var?

luk*_*kle 26 kotlin

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

var greeting: String // Property must be initialized 
get() = "hello"
Run Code Online (Sandbox Code Playgroud)

当我做greeting只读(val)时我不需要初始化

Jan*_*son 31

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

val greeting: String
    get() = "hello"
Run Code Online (Sandbox Code Playgroud)

如果这样做,则生成后备字段并需要初始化.

val greeting: String // Property must be initialized
    get() = field
Run Code Online (Sandbox Code Playgroud)

现在用var.由于默认情况下会生成支持字段,因此必须对其进行初始化.

var greeting: String // Property must be initialized
    get() = "hello"
Run Code Online (Sandbox Code Playgroud)

为了在没有初始化的情况下为var工作,您必须提供自定义setter以防止生成支持字段.例如:

var storage: String = ""
var greeting: String
    get() = "hello"
    set(value) { storage = value}
Run Code Online (Sandbox Code Playgroud)


vod*_*dan 11

您的代码没有自定义setter,因此它相当于:

var greeting: String
    get() = "hello"
    set(v) {field = v}  // Generated by default
Run Code Online (Sandbox Code Playgroud)

默认的set使用实现field,因此您必须初始化它.

按照相同的逻辑,如果你还set没有get使用它,你就不必初始化字段(这意味着它们都是自定义的):

var greeting: String  // no `field` associated!
    get() = "hello"
    set(v) = TODO()
Run Code Online (Sandbox Code Playgroud)

  • 如果您在定义了“get”和“set”时遇到此错误,请确保您没有在任何这些函数中使用“field”引用(如上例中的 setter)。从实现中删除“字段”将消除错误。 (3认同)
  • 如果不需要二传手,则应为`val`属性。 (2认同)