绑定委托属性

对于委托属性,现在可以使用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方法将被委托给这个对象的getValuesetValue方法。属性委托不必实现任何接口,但必须提供 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的示例并未跑通。

results matching ""

    No results matching ""