前言
在 Kotlin 编程的领域中,存在着一个被称为代理(Delegates)的隐藏宝藏。那么什么是Kotlin中的代理?如何实现呢?
Kotlin 代理是什么
在 Kotlin 中,代理是真正的传送管道,使属性的实现委托给另一个实体。简单来说,代理允许我们将getter 和 setter的责任委托给一个单独的类,摆脱重复代码的枷锁。这种机制促进了代码重用、关注点分离和模块化设计。
代理的应用
1. 懒加载代理
只有在首次访问时才会被激活的属性:
val expensiveObject: ExpensiveObject by lazy {
ExpensiveObject()
}
在这个代码片段中,看到 expensiveObject 属性的声明,它被搭配了懒加载代理。花括号中的初始化过程只会在首次访问属性时执行。
2. 可观察代理
借助 Kotlin 标准库中的 ObservableProperty 代理
import kotlin.properties.Delegates
var name: String by Delegates.observable("") { _, oldName, newName ->
println("名称已从 $oldName 变为 $newName")
}
在这段代码片段中,name 属性被赋予了可观察代理。每当 name 的值经历转变时,lambda 表达式将被唤醒,揭示出旧值和新值。在这里,我们可以实现自定义逻辑和编排代码。
3. 映射代理:属性映射
class User(val map: Map<String, Any>) {
val name: String by map
val age: Int by map
}
val user = User(mapOf("name" to "John", "age" to 25))
println(user.name) // 名字:John
println(user.age) // 年龄:25
在这段代码中,User 类装饰着映射代理,优雅地从一个 Map 对象中赋予属性。从此以后,这些属性可以直接访问。
4. 自定义代理:释放定制化
Kotlin 赋予了我们创建自定义代理的能力,可以根据我们的愿望塑造属性行为
import kotlin.reflect.KProperty
class UpperCaseDelegate {
private var value: String = ""
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return value.toUpperCase()
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
value = newValue.toUpperCase()
}
}
class Person {
var name: String by UpperCaseDelegate()
}
val person = Person()
person.name = "John Flk"
println(person.name) // 名字被转化了:JOHN FLK
在这段代码片段中,打造了一个名为 UpperCaseDelegate 的代理。这个代理为分配的值添加了大写形式,无论是在检索还是设置属性时。通过将 Person 类的 name 属性装饰上这个自定义代理,确保了该名字永远以大写的状态存储和检索。