今天看委托模式。
有一篇讲得不错的: 一文彻底搞懂Kotlin中的委托
还有中文官网的教程: 委托属性
还有一篇官方的教程: Kotlin Vocabulary | Kotlin 委托代理
刚开始是不知道这是啥的,像下面的代码:
private val viewmodel: LiveDataViewModel by viewModels { LiveDataVMFactory }
我最看不懂的就是 by
,一头雾水,不知道这里是啥含义,于是便开启了我的学习之旅。
看语法形式:
val/var <属性名>: <类型> by <表达式>
在 by 后面的表达式是该 委托, 因为属性对应的 get()(与 set())会被委托给它的 getValue() 与 setValue() 方法。 属性的委托不必实现任何的接口,但是需要提供一个 getValue() 函数(与 setValue()——对于 var 属性)。
看例子:
import kotlin.reflect.KProperty
class Delegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name}' in $thisRef.")
}
}
class Test {
var name: String by Delegate()
}
fun main(args: Array<String>) {
val test = Test()
test.name = "100"
println(test.name)
}
// 输出:
// 100 has been assigned to 'name' in Test@72ea2f77.
// Test@72ea2f77, thank you for delegating 'name' to me!
可以看到要想委托需要实现对应的方法 getValue
或 setValue
。其中的参数要求:
- thisRef —— 必须与属性所有者类型(对于扩展属性——指被扩展的类型)相同或者是其超类型。
- property —— 必须是类型 KProperty<*> 或其超类型。
- value — 必须与属性类型相同(或者是其超类型)。
其中 thisRef
指的是类,在上面的例子中我编写的是 Any
,所以不受限制,如果我写的是 Int
,那么这里就会失败:
可以看出这里需要的是
Test
或 Test
的超类,当然可以直接写 Any
。既然超类是可以的,那么下面也是可行的:
class Delegate {
operator fun getValue(thisRef: SupperTest?, property: KProperty<*>): String {
return "$thisRef, thank you for delegating '${property.name}' to me!"
}
operator fun setValue(thisRef: SupperTest?, property: KProperty<*>, value: String) {
println("$value has been assigned to '${property.name}' in $thisRef.")
}
}
open class SupperTest
class Test: SupperTest() {
var name: String by Delegate()
}
网友评论