Kotlin扩展函数和带接收者的 Lambda 表达式实现DSL

在 Kotlin 中,​扩展函数 和带接收者的 Lambda 表达式是强大的特性,允许你为现有类添加新功能或创建类型安全的 DSL。以下是详细解释和示例:


1. ​扩展函数(Extension Functions)​​

扩展函数允许在不修改类源码的情况下添加新函数:

kotlin 复制代码
// 为 String 添加扩展函数
fun String.addExclamation(): String = "$this!"

fun main() {
    println("Hello".addExclamation()) // 输出: Hello!
}

2. ​带接收者的 Lambda(Lambda with Receiver)​​

带接收者的 Lambda 是一个特殊的函数类型,其内部可以直接访问接收者对象的成员(类似扩展函数的作用域)。语法为:T.() -> Unit。

示例:标准库中的 apply

scss 复制代码
val sb = StringBuilder().apply {
    append("Hello")  // 直接访问 StringBuilder 的方法
    append(" World")
}

3. ​自定义带接收者的扩展函数​

你可以定义接收带接收者 Lambda 作为参数的扩展函数:

示例:为 StringBuilder添加自定义构建器

kotlin 复制代码
// 接收一个带 StringBuilder 接收者的 Lambda
fun buildString(action: StringBuilder.() -> Unit): String {
    val sb = StringBuilder()
    sb.action() // 执行 Lambda,sb 成为接收者
    return sb.toString()
}

fun main() {
    val result = buildString {
        append("Kotlin") // 在 Lambda 内直接调用 append
        append(" is ")
        append("awesome!")
    }
    println(result) // 输出: Kotlin is awesome!
}

4. ​DSL 应用示例​

带接收者的 Lambda 常用于创建类型安全的 DSL(领域特定语言):

示例:HTML 构建器

kotlin 复制代码
class HTML {
    fun body(action: Body.() -> Unit) { /*...*/ }
}

class Body {
    fun div(action: Div.() -> Unit) { /*...*/ }
}

class Div {
    fun p(text: String) { /*...*/ }
}

fun html(init: HTML.() -> Unit): HTML {
    val html = HTML()
    html.init() // 执行初始化 Lambda
    return html
}

// 使用 DSL 构建 HTML
val myHtml = html {
    body {
        div {
            p("Hello Kotlin DSL!")
        }
    }
}

关键语法总结

概念 语法 说明
​扩展函数​ fun T.myFunc() { ... } 为类型 T添加新函数
​带接收者的 Lambda 类型​ T.() -> Unit Lambda 内部 this指向 T的实例
​调用带接收者的 Lambda​ receiver.action() 将 receiver作为接收者执行 Lambda
​DSL 风格调用​ receiver { ... } Lambda 块内直接访问接收者的成员

通过结合扩展函数和带接收者的 Lambda,你可以创建出高度可读且类型安全的 API,非常适合构建 DSL 或简化复杂对象的初始化。

相关推荐
高频因子挖掘机14 分钟前
500只股票 × 多年日线:数据获取与本地存储如何分工?
后端·github·api
wflynn21 分钟前
GitHub 日榜趋势速报 | 2026-10-16
开源·github
高频因子挖掘机1 小时前
别急着搭数据平台:量化策略开发如何用最小闭环验证想法
后端·github·api
miofly2 小时前
GitHub 今日推荐|sweety-handdraw-video:文章转手绘口播视频
javascript·开源·github
m4Rk_2 小时前
【论文阅读】Agent 记忆机制(102):UMA——用多个未来问题端到端训练一份共享记忆
论文阅读·人工智能·学习·开源·github
adinnet20264 小时前
条件路由与状态传递:自动化员工怎么“分情况办事“和“记上下文“
运维·自动化·github
暗夜铭少5 小时前
用 Go 写了一个单二进制 WAF,聊聊架构取舍和 5 个踩坑点
github
用户2991422196805 小时前
GitHub 热榜项目:日榜(2026-10-17)
人工智能·开源·github
wflynn6 小时前
GitHub 今日推荐|open_scion:为AI代理设计的并发版本控制
git·开源·go·github·agent·coding-agents
u1301306 小时前
GitHub 热榜项目:日榜(2026-10-16)
人工智能·github