Kotlin 扩展函数

214 阅读2分钟
一、核心概念
  1. 定义与作用
    扩展函数(Extension Functions)允许开发者‌在不修改原类代码‌的情况下,为现有类(包括第三方库或系统类)添加新的功能,遵循“开放-封闭原则”37。例如,为 String 类添加统计字母数量的方法,无需继承或修改 String 源码。

  2. 语法结构
    扩展函数通过 fun 接收者类型.函数名() 声明,函数体中可用 this 访问接收者对象:

    // 示例:为 String 添加统计字母数量的扩展函数
    fun String.lettersCount(): Int {
        var count = 0
        for (char in this) {
            if (char.isLetter()) count++
        }
        return count
    }
    

    调用时通过 "ABC123".lettersCount() 直接使用8。

  3. 静态解析特性
    扩展函数是‌编译时静态绑定‌的,调用时由接收者变量的声明类型决定,而非运行时实际类型34。例如:

    open class C
    class D : C()
    fun C.foo() = "C"
    fun D.foo() = "D"
    
    val d: C = D()
    println(d.foo()) // 输出 "C"(依据声明类型 C 调用)
    

二、常见应用场景
  1. 增强第三方库或系统类
    RecyclerView 添加快速设置 Adapter 的方法:

    fun RecyclerView.setup(adapter: RecyclerView.Adapter<*>) {
        this.adapter = adapter
        layoutManager = LinearLayoutManager(context)
    }
    

    调用时:recyclerView.setup(adapter)6。

  2. 替代工具类,简化代码
    将工具函数转为扩展函数,提升可读性:

    // 替代 DateUtils.formatTimestamp(time) → time.formatTimestamp()
    fun Long.formatTimestamp(): String = SimpleDateFormat("yyyy-MM-dd").format(Date(this))
    

    调用方式更直观:System.currentTimeMillis().formatTimestamp()68。

  3. 链式调用优化
    结合扩展函数与原方法实现链式操作:

    "hello".capitalize().addExclamation().repeat(2) // 输出 "Hello!Hello!"
    
  4. 空安全处理
    为可空类型添加安全操作:

    fun String?.safeLength(): Int = this?.length ?: 0
    val length = nullableString.safeLength() // 避免空指针异常
    ```:ml-citation{ref="6" data="citationList"}
    

三、高级用法
  1. 泛型扩展函数
    为泛型类添加通用功能,如标准库的 let 函数:

    fun <T, R> T.let(block: (T) -> R): R = block(this)
    

    使用示例:

    user?.let { println(it.name) } // 安全调用
    ```:ml-citation{ref="5,6" data="citationList"}。
    
  2. 为 Any 类定义扩展
    Any 定义扩展函数后,所有子类均可使用:

    fun Any.printClassName() = println(this::class.simpleName)
    123.printClassName() // 输出 "Int"
    "text".printClassName() // 输出 "String"
    ```:ml-citation{ref="5" data="citationList"}。
    

四、注意事项
  1. 优先级规则
    当扩展函数与类成员函数同名时,‌成员函数优先调用‌4。例如:

    class User { fun show() = println("Member") }
    fun User.show() = println("Extension")
    
    User().show() // 输出 "Member"
    
  2. 不可访问私有成员
    扩展函数仅能访问接收者类的 publicprotected 成员,无法直接操作私有属性47。

  3. 避免滥用
    过度使用扩展函数可能导致代码可读性降低,建议优先通过继承或组合扩展功能78。


五、总结

Kotlin 扩展函数通过简洁的语法和静态绑定特性,解决了代码冗余和第三方库扩展难题,广泛应用于增强类功能、优化工具方法及空安全处理36。使用时需注意优先级、作用域限制及合理设计,避免过度扩展。