当前位置:嗨网首页>书籍在线阅读

14-提供委托

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

9.3.6 提供委托

通过provideDelegate操作符,Kotlin允许扩展创建属性以及实现所委托对象的逻辑。通常,使用操作符provideDelegate将by右侧的对象定义为成员或扩展函数,调用该函数来创建属性的委托实例。

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操作符创建属性时(不仅仅在getter或setter 方法中使用),可以检查属性的一致性,provideDelegate的参数与getValue相同。

  • thisRef:该参数必须与属性所有者类型相同或者是其超类型。
  • prop:该参数必须是类型KProperty<*>或其超类型。

在上面的代码中,当创建MyUI实例时,系统会调用provideDelegate方法实现属性与委托之间的绑定关系并执行相关的校验操作。相对于属性声明编译生成的代码,使用provideDelegate生成的代码如下。

class C {
    var prop: Type by MyDelegate()
}
//由编译器生成的provideDelegate代码
class C {
    // 调用provideDelegate来创建额外的delegate属性
    private val prop$delegate = MyDelegate().provideDelegate(this, this::prop)
    val prop: Type
        get() = prop$delegate.getValue(this, this::prop)
}

在生成的代码中,provideDelegate方法只会辅助属性的创建,并不会影响为getter或setter生成的代码。