gpt4 book ai didi

kotlin - 为什么属性初始化器不调用自定义 setter ?

转载 作者:IT老高 更新时间:2023-10-28 13:31:51 27 4
gpt4 key购买 nike

来自 Kotlin documentation , 允许自定义 setter :

class Test {
var stringRepresentation: String
get() = field
set(value) {
setDataFromString(value)
}

init {
stringRepresentation = "test"
}

private fun setDataFromString(value: String) { }
}

但是你不能有一个没有自定义 getter 的自定义 setter(并从 init block 初始化):

class Test {
// Compilation error: "Property must be initialized"
var stringRepresentation: String
set(value) {
setDataFromString(value)
}

init {
stringRepresentation = "test"
}

private fun setDataFromString(value: String) { }
}

虽然您可以在没有自定义 setter 的情况下使用自定义 getter,但这里没有问题:

class Test {
var stringRepresentation: String
get() = field

init {
stringRepresentation = "test"
}

private fun setDataFromString(value: String) { }
}

那么为什么不能使用自定义 setter 和从 init block 中初始化的属性,以及为什么 init block 在属性时调用自定义 setter 初始化器直接赋值,绕过自定义 setter ?

class Test {
var stringRepresentation: String = "" // Does not call custom setter
set(value) {
setDataFromString(value)
}

init {
stringRepresentation = "test" // Calls custom setter
}

private fun setDataFromString(value: String) { }
}

最佳答案

属性初始化器不调用自定义 setter ,因为它们的目的是提供默认值。

与 Java 不同,在 Kotlin 中,不仅局部变量必须在首次访问之前初始化,而且类属性也必须初始化。

在 Java 中这是有效的。

public class Test {
public String str;

public static void main(String[] args) {
System.out.println(new Test().str);
}
}

在 Kotlin 中不是这样。

class Parent {
var str: String?
}

fun main(args: Array<String>) {
Parent().str
}

因此,自定义 setter 需要由属性初始化程序或构造函数初始化其属性。看看下面的例子。

class Test {
var stringRepresentation: String = "a" // Default value. Does not call custom setter
get() = field
set(value) {
println("Setting stringRepresentation property to %s. Current value is %s.".format(value, field))
field = setDataFromString(value)
}

init {
this.stringRepresentation = "b" // Calls custom setter
}

private fun setDataFromString(value: String): String {
println("Setting stringRepresentation property to %s.".format(value))
return value
}
}

fun main(args: Array<String>) {
Test().stringRepresentation = "c" // Calls custom setter
}

属性 stringRepresentation 在其类的实例化时初始化为 "a" opon,无需调用 setter。然后调用 init block 并使用 setter 将值设置为 "b"。然后使用 setter 到 "c"

关于kotlin - 为什么属性初始化器不调用自定义 setter ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41214452/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com