一文弄懂Kotlin中的by关键字

在 Kotlin 中,by 关键字用于实现委托模式(Delegation)​ ,它允许将某些操作或责任委托给另一个对象来处理。by 主要有两种用途:​类委托属性委托


1. 类委托(Class Delegation)

通过 by 关键字,可以将类的接口实现委托给另一个对象。这样可以在不继承的情况下复用现有类的功能。

示例:

kotlin 复制代码
interface Animal {
    fun makeSound()
}

class Dog : Animal {
    override fun makeSound() {
        println("Woof!")
    }
}

// 通过 by 将 Animal 接口的实现委托给 dog 对象
class Robot(private val dog: Dog) : Animal by dog {
    fun move() {
        println("Robot is moving")
    }
}

fun main() {
    val dog = Dog()
    val robot = Robot(dog)
    robot.makeSound() // 实际调用的是 Dog 的 makeSound()
    robot.move()      // Robot 的独有方法
}
  • 作用Robot 类通过 by dog 委托了 Animal 接口的实现,无需手动重写 makeSound()
  • 优势:避免重复代码,优先组合而非继承。

2. 属性委托(Property Delegation)

通过 by 将属性的 getter/setter 逻辑委托给一个委托对象 ​(需实现 getValue()setValue() 方法)。Kotlin 标准库提供了几种常用委托:

常见用途:

(1)懒加载委托 lazy

属性在首次访问时初始化。

kotlin 复制代码
val heavyData: String by lazy {
    println("Computing heavy data...")
    "Heavy Result"
}

fun main() {
    println(heavyData) // 第一次访问时计算并缓存
    println(heavyData) // 直接返回缓存结果
}
(2)观察者委托 Delegates.observable

属性变化时触发回调。

kotlin 复制代码
import kotlin.properties.Delegates

var name: String by Delegates.observable("Alice") { _, old, new ->
    println("Name changed: $old -> $new")
}

fun main() {
    name = "Bob" // 输出: Name changed: Alice -> Bob
}
(3)非空校验委托 Delegates.notNull

延迟初始化但确保非空。

kotlin 复制代码
var age: Int by Delegates.notNull<Int>()

fun main() {
    age = 30
    println(age) // 必须先赋值,否则抛 IllegalStateException
}
(4)自定义委托

实现 ReadWritePropertyReadOnlyProperty 接口。

kotlin 复制代码
class StringDelegate(private var value: String) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("Getting value: $value")
        return value
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) {
        println("Setting value: $newValue")
        value = newValue
    }
}

var text by StringDelegate("Default")

fun main() {
    println(text) // 输出: Getting value: Default
    text = "New"  // 输出: Setting value: New
}

关键点总结:

  • 类委托 :通过 by 将接口实现委托给其他对象。
  • 属性委托 :将属性的访问逻辑委托给 lazyobservable 或自定义对象。
  • 优势:减少重复代码,实现关注点分离(如懒加载、观察模式等)。

通过 by,Kotlin 以简洁的语法实现了强大的委托模式,是 Kotlin 特色功能之一。

相关推荐
用户1982333188403 小时前
让PAG动画在富文本中动起来
android·kotlin
hudawei9965 小时前
kotlin中withContext,async,launch几种异步的区别
android·开发语言·kotlin
消失的旧时光-19435 小时前
Kotlin 常用语法糖完整整理
android·开发语言·kotlin
每次的天空5 小时前
Android-重学kotlin(协程源码第一阶段)新学习总结
开发语言·学习·kotlin
金銀銅鐵20 小时前
[Kotlin] 单例对象是如何实现的?
java·kotlin
Devil枫1 天前
Kotlin项目实战与总结
开发语言·jvm·kotlin
yeziyfx1 天前
kotlin中集合的用法
android·开发语言·kotlin
一只柠檬新1 天前
Kotlin object单例到底是懒汉式还是饿汉式
android·kotlin
hsx6662 天前
Kotlin 协程中的 Dispatchers
kotlin
每次的天空2 天前
Android-重学kotlin(协程源码第二阶段)新学习总结
android·学习·kotlin