Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 标准库中的委托属性:lazy、Delegates.observable

标准库中的委托属性:lazy、Delegates.observable

1. 委托属性简介

委托属性(Delegated Properties)是 Kotlin 提供的一种强大特性,允许将属性的 getter 和 setter 逻辑委托给另一个对象处理。Kotlin 标准库内置了多种实用的委托属性实现,如 lazy 和 Delegates.observable,可以简化代码并增强功能。


2. lazy 委托

2.1 基本用法

lazy 用于实现属性的惰性初始化(延迟加载),即属性值在第一次访问时才计算并缓存,后续访问直接返回缓存值。

val expensiveResource: String by lazy {
    println("Initializing expensive resource...")
    "Loaded Data"
}

fun main() {
    println(expensiveResource) // 第一次访问时初始化
    println(expensiveResource) // 直接返回缓存值
}

2.2 线程安全模式

lazy 默认是线程安全的(通过 LazyThreadSafetyMode.SYNCHRONIZED),但可以通过参数指定其他模式:

  • SYNCHRONIZED(默认):线程安全,但性能略低。
  • PUBLICATION:允许多线程初始化,但仅第一个结果被缓存。
  • NONE:非线程安全,适合单线程环境。
val unsafeLazyValue: Int by lazy(LazyThreadSafetyMode.NONE) {
    Thread.sleep(1000)
    42
}

3. Delegates.observable 委托

3.1 监听属性变化

Delegates.observable 允许在属性值发生变化时触发回调,适用于数据绑定或日志记录等场景。

import kotlin.properties.Delegates

var observedValue: String by Delegates.observable("Initial") { 
    property, oldValue, newValue ->
    println("${property.name} changed from $oldValue to $newValue")
}

fun main() {
    observedValue = "New Value" // 输出: observedValue changed from Initial to New Value
}

3.2 结合验证逻辑

可以通过返回布尔值的条件进一步控制赋值是否生效(Delegates.vetoable):

var positiveNumber: Int by Delegates.vetoable(0) { _, old, new ->
    new > 0 // 仅允许正数赋值
}

fun main() {
    positiveNumber = 10 // 成功
    println(positiveNumber) // 10
    positiveNumber = -5 // 失败,保持原值
    println(positiveNumber) // 10
}

4. 其他标准库委托

4.1 Delegates.notNull

用于非空属性的延迟初始化(类似 lateinit,但支持基本类型):

var notNullValue: Int by Delegates.notNull()

4.2 自定义委托

通过实现 ReadOnlyProperty 或 ReadWriteProperty 接口,可以创建自定义委托:

class CustomDelegate : ReadWriteProperty<Any?, String> {
    private var storedValue = "Default"
    override fun getValue(thisRef: Any?, property: KProperty<*>): String = storedValue
    override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        storedValue = value.toUpperCase()
    }
}

var customProperty: String by CustomDelegate()

5. 总结

委托类型用途特点
lazy惰性初始化线程安全、缓存结果
Delegates.observable监听属性变化支持旧值/新值回调
Delegates.vetoable条件性赋值可拦截无效赋值
Delegates.notNull延迟初始化的非空属性支持基本类型

通过合理使用这些委托属性,可以显著减少样板代码并提升代码的可维护性。

Last Updated:: 5/21/25, 7:58 PM