第十一章 DSL构建
这一章会讨论怎样使用领域特定语言DSL(Domain-Specific-Language)为Kotlin类设计更有表现力、更符合语言习惯的API。
Kotlin DSL依赖于众多的语言特性,本章会完整讨论两个:带接收者的lambda(第五章介绍过)和invoke约定。
11.1 从API到DSL
我们的目标是尽可能地让代码具有最佳可读性和可维护性。因此不仅要关注单独的类,更重要的是要关注交互发生的接口-也就是类的API。
一个API整洁的标准:
- 需要能够让读者清楚地知道在代码中发生了什么。这可以通过选择良好的名称和概念来做到。
- 代码需要看起来整洁,极少使用浮夸的代码且不存在多余的语法。这也是本章关注的目标。
Kotlin允许构建整洁API的功能的代表包括:
- 扩展函数
- 中缀调用
- lambda简明语法
- 运算符重载
DSL比由单独方法构造出的API更具表现力且更适宜工作。
Kotlin的DSL是完全静态类型的。
11.1.1 领域特定语言的概念
有两个相对概念:
- 通用编程语言(GPL):有一系列足够完善的能力来解决几乎所有能被计算机解决的问题。
- 领域特定语言(DSL):专注在特定任务或者领域上,并放弃与该领域无关的功能。
常见的DSL有SQL和正则表达式。
这类DSL的优点或者说特点:
- 通过减少提供的功能来有效完成目标
- 更趋向于声明式。
有一个缺点:很难与使用通用编程语言的宿主应用程序结合起来使用。
要解决上述DSL的缺点,并且保留优点,目前有个概念是内部DSL。
11.1.2 内部DSL
内部DSL是用通用编程语言编写的程序的一部分,使用语言的特定方式,保留具有独立语法的DSL的主要优点。
示例为Exposed框架,Kotlin编写的用来访问数据库的框架。请自行搜索查看demo。
11.1.3 DSL的结构
DSL与普通的API之间没有明确定义的边界,但DSL中经常会出现一个通常在其他API中不存在的特征:结构或者说是文法。
在Kotlin DSL中,结构通常是通过嵌套的lambda表达式或链式方法调用来创建。
这种文法使得能够将一个内部DSL称作一门语言。
DSL结构的一个好处是允许在多个函数调用之间重用一个上下文。
11.1.4 使用内部DSL构建HTML
示例:
fun createSimpleTable() = createHTML().
table{
tr{
td{ +"cell" }
}
}
//对应的HTML
<table>
<tr>
<td>cell</td>
</tr>
</table>
示例是kotlinx.html库里的代码,下面一节会讲解说明。
11.2 构建结构化的API:DSL中带接受者的lambda
11.2.1 带接受者的lambda和扩展函数类型
1.扩展函数类型
扩展函数类型:在声明的时候,将普通函数类型签名中的一个参数(类型)移到括号前面,并用一个.将它与其他的参数(类型)分隔开。
示例:
StringBuilder.() -> Unit
String.(int,int) -> Unit
//相当于
(StringBuilder)

最低0.47元/天 解锁文章
802

被折叠的 条评论
为什么被折叠?



