绑定委托属性
对于委托属性,现在可以使用provideDelegate操作符拦截委托属性绑定使用。例如,如果我们想要绑定属性之前检查属性名,我们可以写出这样的:
class ResourceLoader<T>(id: ResourceID<T>) {
operator fun provideDelegate(thisRef: MyUI, prop: KProperty<*>): ReadOnlyProperty<MyUI, T> {
checkProperty(thisRef, prop.name)
}
private fun checkProperty(thisRef: MyUI, name: String) { ... }
}
fun <T> bindResource(id: ResourceID<T>): ResourceLoader<T> { ... }
class MyUI {
val image by bindResource(ResourceID.image_id)
val text by bindResource(ResourceID.text_id)
}
provideDelegate方法会在创建MyUI实例的每个属性时候进行调用。,并且可以马上对属性进行验证。
val/var <属性名>: <类型> by <表达式>
by 关键字之后的表达式就是委托,属性的getter和setter方法将被委托给这个对象的getValue和setValue方法。属性委托不必实现任何接口,但必须提供 getValue() 函数(对于 var属性,还需要 setValue() 函数)。
class Example {
var p: String by Delegate()
}
// 委托的类
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, 这里委托了 ${property.name} 属性"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$thisRef 的 ${property.name} 属性赋值为 $value")
}
}
fun main(args: Array<String>) {
val e = Example()
println(e.p) // 访问该属性,调用 getValue() 函数
e.p = "Runoob" // 调用 setValue() 函数
println(e.p)
}
provideDelegate的示例并未跑通。