Kotlin Var 和 Val Getter 和 Setter 问题

Jit*_*ali 0 android kotlin val

我是 Kotlin 编程语言的新手。(Java -> Kotlin)

var x
    get()= 4; // Showing error Property must be initialized

val y
    get()= 4; // No error
Run Code Online (Sandbox Code Playgroud)

为什么会出现这种情况?

cac*_*acs 6

val y = 4是一个val,这意味着它是只读的。您初始化它的值4存储在支持字段中。存储该变量值的一段内存。

var y = 4是一个var,这意味着您可以写入它。同样,有一个支持字段存储当前值 - 只是您现在可以更改它。


这可能是您已经习惯的所有内容 - 但 Kotlin 还允许您定义getter 和 setter 函数,具体取决于它是val(仅 getter)还是var. 实际上,默认的 getter 和 setter 已经存在 - 它们只是读取和写入支持字段。如果您没有定义自己的,它只会使用它们。

val y get() = 4是一个val,这意味着它是只读的。因为您添加了一个 getter 函数,所以该4值实际上并未存储在支持字段中 - 因此 Kotlin 不会创建一个!没有什么可以用值初始化的。

var y get() = 4是一个var,所以你可以设置它。您尚未在此处定义 setter 函数,因此它使用隐式默认函数,该函数写入支持字段。

这就是你的问题所在 - 如果 Kotlin 不需要支持字段,则它不会创建支持字段:

// stores any value passed to the setter in the variable's backing field
var something
    get() = "hi"
    set(value) { field = value }

// does nothing with the setter value, no field is used anywhere, so it doesn't create one
var somethingElse
    get() = "hi"
    set(value) { }
Run Code Online (Sandbox Code Playgroud)

(这不是一个很好的例子,因为通常你不会有一个带有 setter 的固定值,因为这有什么意义?但是你可以有一个 getter/setter 对来存储和读取地图或其他东西,这不会'不需要支持字段,因为它在其他地方获取和存储数据)


因此,当你这样做时,var y get() = 4你实际上是在这样做:

var y
    get() = 4
    set(value) { field = value } // default setter
Run Code Online (Sandbox Code Playgroud)

这就是通过二传手创建一个支持场。该字段需要有一些初始值!Kotlin 与 Java 不同,Java 中的事物可以保持未分配状态并默认为某个值。

所以你只需要分配一个值:

var y = 1
    get() = 4
Run Code Online (Sandbox Code Playgroud)

现在你的支持字段有了一个值,所以编译器很高兴。var您从未真正阅读过它,因此它毫无用处,这是一个好兆头,您根本不需要它!

查看属性文档,它解释了所有这些内容(以及有关可见性等的其他一些内容),但希望这是有意义的,并且您可以明白为什么您的示例实际上有点奇怪以及您应该避免的事情。