简体   繁体   中英

Initialize variable in init block and define a setter for the variable in kotlin

I want to write this piece of code but it doesn't work.

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

init {
    a = 2
}

I have to initialitze the variable when I declare it. Why does it happen? How can I solve it?

Your property has a custom setter, and when you call a = 2 in the init block, that setter's code will run.

That code could be arbitrarily complex, and the compiler can't know for sure whether it will end up setting the value of the backing field of the property or not. In your code example, it would set the backing field, and your property would be in a valid state.

However, you could also have a custom setter such as this one:

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

Calling this in an init block would not necessarily would be enough, as it might leave the property in an uninitialized state.

To prevent this, the compiler asks you to set a value to the property at its declaration instead when using custom setters.

Maybe you have another context but basically you can initialize it just by assigning a value to the field

private var a: Int = 3

This won't execute your setter. If this is a static value (an initial state of the class) then it should be fine.

If the value of a is set at runtime in the init block then and its value depends on some existing logic then you can use a property delegate

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
}

There may be other solutions but for that we need to know more about your context.

You are asking why you have to initialitze the variable? Well, you can not have uninitialitzed variables.

You must initialize properties either when you declare them or in the init block.

If you want to have it unitialized first, you have to make it nullable and set it to null when you declare it:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM