DSL 构建
类型安全的构建器、@DslMarker、lambda with receiver
DSL 构建
Kotlin 的 lambda with receiver 让构建类型安全的 DSL 变得自然——Gradle Kotlin DSL 就是例子。
学完本章你将: 掌握 lambda with receiver、@DslMarker、HTML DSL。
lambda with receiver
kotlin
fun buildString(action: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.action()
return sb.toString()
}
val result = buildString {
append("Hello, ")
append("World!")
}
// "Hello, World!"
简单 HTML DSL
kotlin
class HTML {
private val children = mutableListOf<String>()
fun body(block: Body.() -> Unit) {
val body = Body()
body.block()
children.add("<body>${body.content}</body>")
}
override fun toString() = children.joinToString("\n")
}
class Body {
var content = ""
fun p(text: String) { content += "<p>$text</p>\n" }
fun h1(text: String) { content += "<h1>$text</h1>\n" }
}
fun html(block: HTML.() -> Unit): HTML {
return HTML().apply(block)
}
val page = html {
body {
h1("标题")
p("段落内容")
}
}
@DslMarker
kotlin
@DslMarker
annotation class HtmlDsl
@HtmlDsl
class HTML { ... }
// 防止隐式访问外层接收者——避免混乱