推荐答案
Kotlin 中的标准委托主要包括以下几种:
- Lazy:延迟初始化属性,只有在第一次访问时才会计算值。
- Observable:监听属性的变化,并在属性值发生变化时触发回调。
- Vetoable:与
Observable类似,但可以在属性值发生变化之前进行拦截和否决。 - NotNull:用于确保属性在初始化时不为空。
- Map:将属性委托给一个
Map,属性名作为键,属性值作为值。
本题详细解读
Lazy
Lazy 委托用于延迟初始化属性。它接受一个 lambda 表达式,该表达式在第一次访问属性时执行,并返回属性的初始值。之后,该值会被缓存,后续访问将直接返回缓存的值。
val lazyValue: String by lazy {
println("computed!")
"Hello"
}
println(lazyValue) // 输出: computed! Hello
println(lazyValue) // 输出: HelloObservable
Observable 委托用于监听属性的变化。它接受两个参数:初始值和一个回调函数。当属性值发生变化时,回调函数会被触发。
var observableValue: String by Delegates.observable("Initial Value") {
_, old, new ->
println("Value changed from $old to $new")
}
observableValue = "New Value" // 输出: Value changed from Initial Value to New ValueVetoable
Vetoable 委托与 Observable 类似,但它允许在属性值发生变化之前进行拦截和否决。回调函数返回一个布尔值,如果返回 false,则属性值不会被更新。
// www.javascriptcn.com code example
var vetoableValue: Int by Delegates.vetoable(0) {
_, old, new ->
println("Attempting to change value from $old to $new")
new > old // 只有新值大于旧值时才会更新
}
vetoableValue = 10 // 输出: Attempting to change value from 0 to 10
println(vetoableValue) // 输出: 10
vetoableValue = 5 // 输出: Attempting to change value from 10 to 5
println(vetoableValue) // 输出: 10 (值未改变)NotNull
NotNull 委托用于确保属性在初始化时不为空。如果在访问属性时它还未被初始化,则会抛出 IllegalStateException。
var notNullValue: String by Delegates.notNull() notNullValue = "Initialized" println(notNullValue) // 输出: Initialized // notNullValue = null // 编译错误,不能赋值为 null
Map
Map 委托用于将属性委托给一个 Map,属性名作为键,属性值作为值。这在处理动态属性时非常有用。
// www.javascriptcn.com code example
class User(val map: Map<String, Any?>) {
val name: String by map
val age: Int by map
}
val user = User(mapOf(
"name" to "John Doe",
"age" to 25
))
println(user.name) // 输出: John Doe
println(user.age) // 输出: 25这些标准委托为 Kotlin 提供了强大的属性管理功能,使得代码更加简洁和易于维护。