DSL 的全称是领域特定语言(Domain Specific Language),它是编程语言赋予开发者的一种特殊能力,通过它我们可以编写出一些看似脱离其原始语法结构的代码,从而构建出一种专有的语法结构。
在 Kotlin 中,实现 DSL 的方式并不固定。这里主要的学习目标是通过高阶函数的方式来实现 DSL,这也是 Kotlin 中实现 DSL 中最常见的方式。
在 Android 中,Gradle 是一种基于 Groovy 语言的构建工具,因此,当我们在 build.gradle 中添加依赖库时所编写的内容其实就是 Groovy 提供的 DSL 功能。下面借助 Kotlin 的 DSL,来实现类似的语法结构:
示例(Kotlin):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| fun main() { val libraries = dependencies { implementation("com.squareup.retrofit2:retrofit:2.6.1") implementation("com.squareup.retrofit2:converter-gson:2.6.1") } for (lib in libraries) { println(lib) }
}
class Dependency {
val libraries = ArrayList<String>()
fun implementation(lib:String){ libraries.add(lib) } }
fun dependencies(block: Dependency.() -> Unit):List<String>{ val dependency = Dependency() dependency.block() return dependency.libraries }
|
示例(Kotlin):动态生成表格所对应的 HTML 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| fun main() { val html = table { tr { td { "Apple" } td { "Grape" } td { "Orange" } } tr { td { "Pear" } td { "Banana" } td { "Watermelon" } } } val html1 = table { repeat(2) { tr { val fruits = listOf("Apple", "Grape", "Orange") for (fruit in fruits) { td { fruit } } } } }
println(html) println(html1)
}
class Td { var content = "" fun html() = "\n\t\t<td>$content</td>" }
class Tr { private val children = ArrayList<Td>() fun td(block: Td.() -> String) { val td = Td() td.content = td.block() children.add(td) } fun html(): String { val builder = StringBuilder() builder.append("\n\t<tr>") for (childTag in children) { builder.append(childTag.html()) } builder.append("\n\t</tr>") return builder.toString() } } class Table { private val children = ArrayList<Tr>()
fun tr(block: Tr.() -> Unit) { val tr = Tr() tr.block() children.add(tr) }
fun html(): String { val builder = StringBuilder() builder.append("<table>") for (childTag in children) { builder.append(childTag.html()) } builder.append("\n</table>") return builder.toString() } }
fun table(block: Table.() -> Unit): String { val table = Table() table.block() return table.html() }
|
备注
参考资料:
第一行代码(第3版)