💬 什么是 Kotlin DSL?

DSL 就像你用 Kotlin 写的“小语言”或“专属语法”。

比如你写一个配置文件或者描述页面内容时,希望这样写:

1
2
3
4
5
6
7
8
9
page {
title = "欢迎来到我的网站"
header {
text = "Hello!"
}
paragraph {
text = "这里是正文内容"
}
}

看起来像“自己发明的语言”,对吧?这个就是 Kotlin DSL 的目标:写出接近自然语言的代码,让代码更“会说话”。


🧱 怎么做?用 Kotlin 的 3 个小技巧就可以了:

1️⃣ 高阶函数(函数里面传函数)

1
2
3
fun doSomething(block: () -> Unit) {
block()
}

你可以这样用:

1
2
3
doSomething {
println("Hello")
}

2️⃣ Lambda with Receiver(这个超重要,是 DSL 的核心)

看个例子:

1
2
3
4
5
6
7
8
9
10
11
12
class Person {
var name = ""
fun sayHello() {
println("Hello, my name is $name")
}
}

fun createPerson(block: Person.() -> Unit): Person {
val person = Person()
person.block() // 注意是 person.block()
return person
}

这样用:

1
2
3
4
val p = createPerson {
name = "Tom"
sayHello()
}

是不是很像自己在写一门“人类建造语言”?这就是 DSL 的味道!


3️⃣ apply 是帮你省代码的神器

等价于:

1
2
3
val person = Person()
person.name = "Tom"
person.sayHello()

写成:

1
2
3
4
val person = Person().apply {
name = "Tom"
sayHello()
}

🛠 我们做个最简单的 DSL 示例:构建菜单

我们希望能这样写代码:

1
2
3
4
5
menu {
item("打开")
item("保存")
item("退出")
}

👉 DSL 实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Menu {
private val items = mutableListOf<String>()

fun item(name: String) {
items.add(name)
}

fun show() {
println("菜单内容:")
items.forEach {
println(" - $it")
}
}
}

fun menu(block: Menu.() -> Unit): Menu {
val m = Menu()
m.block()
return m
}

✅ 使用:

1
2
3
4
5
6
val myMenu = menu {
item("打开")
item("保存")
item("退出")
}
myMenu.show()

输出:

1
2
3
4
菜单内容:
- 打开
- 保存
- 退出

✅ 小结一句话:

Kotlin DSL = 自己写一个函数(用 lambda with receiver) + 定义类结构 + apply(),就能造出一套看起来像“自己写的语言”的代码。