在init块中初始化变量,并在kotlin中为变量定义setter



我想写这段代码,但是它不起作用。

private var a: Int
set(value) {
field = a
// Code
}
init {
a = 2
}

我必须在声明变量时初始化它。为什么会这样呢?我怎么解它?

您的属性有一个自定义setter,当您在init块中调用a = 2时,该setter的代码将运行。

该代码可能是任意复杂的,并且编译器不能确定它最终是否会设置属性的backing字段的值。在您的代码示例中,它将设置支持字段,并且您的属性将处于有效状态。

但是,您也可以有一个自定义设置器,例如:

private var a: Int
set(value) {
if (value > 0) {
field = value
}
}

init块中调用它不一定足够,因为它可能使属性处于未初始化状态。

为了防止这种情况,编译器会要求您在使用自定义setter时,在声明属性时设置一个值。

也许你有其他的上下文但是基本上你可以通过给字段赋值来初始化它

private var a: Int = 3

不会执行你的setter。如果这是一个静态值(类的初始状态),那么应该没问题。

如果a的值是在运行时在init块中设置的,那么它的值取决于一些现有的逻辑,那么你可以使用属性委托

private var readWrite: Int by resourceDelegate()
fun resourceDelegate(): ReadWriteProperty<Any?, Int> =
object : ReadWriteProperty<Any?, Int> {
var curValue = 0
override fun getValue(thisRef: Any?, property: KProperty<*>): Int = curValue
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
println("Setting value using resource delegate")
curValue = value
}
}
init {
readWrite = 4
}

可能有其他的解决方案,但为此我们需要更多地了解您的环境。

你在问为什么你必须初始化变量?你不能有未初始化的变量

必须在声明属性时或在init块中初始化属性。

如果你想让它先初始化,你必须让它为空,并在声明它时将其设置为null:

private var a: Int? = null
set(value: Int?) {
// ...
}

最新更新