Property Delegation Tools
The standard library contains special property delegation properties. Map
is one of the few types in Kotlin library. Each property identifier becomes a String
key for the map, and the property’s type is captured in the associated value:
class Student(map: MutableMap<String, Any?>) {
var name: String by map
var age: Int by map
var id: String by map
}
val aStudent = mutableMapOf<String, Any?>(
"name" to "Jeep",
"age" to 23,
"id" to "X231322"
)
Property Setter vs Delegate Observable
We might remember using set
to set a new value to the var
.
var name: String
set(value) {
print("name: $value")
field = value
}
var age: Int
set(value) {
print("age: $value")
field = age
}
While property setter works fine, Delegates, on the other hand, allows for accessing to the property and its old value.
class Student {
var log = ""
var surname: String by observable("x") { prop, old, new ->
log += "${prop.name}: $old -> $new"
}
}
val student = Student()
student.surname = "Lee"
print(student.log) // surname: x -> Lee
observable
takes two arguments:
- initialValue, “x” in this case
- a function to invoke when there is
onChange
event occurs.
delegate vetoable
it is very similar to observable
in delegate, but it can veto the modification of the value of property. For example, we might have some rule that the student surname must be more than one character for some reasons.
fun surnameLengthCheck(
property: KProperty<*>,
old: String,
new: String
) = return new.length > 1
class Student {
var surname: String by Delegates.vetoable("Lee", ::surnameLengthCheck)
}
val student = Student()
student.surname = "Tan"
student.surname = "x"
print(student.surname) //Tan and x is rejected because it fails surnameLengthCheck
delegate notNull
The last function in delegate
is nonNull
. It returns on property delegate for read/write with a non-null
value. It is initialized not during the object construction time, but later time. It tries to read the property before the initial value has been assigned.
Conclusion
As we can see delegates
function in the kotlin standard library could be used to guard or trace about the setting of new value. notNull
, observable
and vetoable
could be used to customize for setting or tracing new value.