I am reading this page about Delegated properties
in Kotlin doc site.
import kotlin.reflect.KProperty
class Example {
var p: String by Delegate() // 1
override fun toString() = "Example Class"
}
class Delegate() {
operator fun getValue(thisRef: Any?, prop: KProperty<*>): String { // 2
return "$thisRef, thank you for delegating '${prop.name}' to me!"
}
operator fun setValue(thisRef: Any?, prop: KProperty<*>, value: String) { // 2
println("$value has been assigned to ${prop.name} in $thisRef")
}
}
fun main() {
val e = Example()
println(e.p)
e.p = "NEW"
}
The output is:
Example Class, thank you for delegating 'p' to me!
NEW has been assigned to p in Example Class
And I can understand the result.
But my question is, what if I print the e.p
again after setting its value as NEW
:
fun main() {
val e = Example()
println(e.p)
e.p = "NEW"
println(e.p) // print it again after setting new value on it
}
I expect it to print NEW
. But the actual result is, it kept the same as the 1st println: Example Class, thank you for delegating 'p' to me!
.
Kotlin playground at here.
Seems like the e.p = "NEW"
cannot change the value correctly. What causes that? What do I do if I want to set the value as NEW
?
CodePudding user response:
Your delegate class instance completely takes over what the getter and setter of the property do. Since your delegate’s setValue
function doesn’t actually store the passed-in value in any internal property, it’s getValue
function has no way to retrieve and return it. And indeed, the implementation of getValue()
in your code is only generating a String and returning that.
When you get the value of the delegated property, it returns whatever your delegate returns in getValue()
, so the behavior is determined by how you program your delegate class.