Kotlin创建DSL
<Kotlin从入门进阶到实战>
什么是DSL
DSL(Domain-Specific Language,领域特定语言)指的是专注于特定问题领域的计算机语言。不同于通用的计算机语言,领域特定语言之用在某些特定的领域。DSL语言让我们更简洁的方式来表达和解决领域问题。简单的讲就是对一个特定的问题的方案模型更高层次的抽象表达。使其更加简单易懂。
DSL只是问题解决方案的外部封装。这个模型可能是一个API库,也可能是一个完整的框架。典型的例子是用于替代Android开发中布局XML文件的DSL框架Anko,它使用与基于Kotlin的DSL来盛名Android UI组件,为不是传统的XML。
XML本质上来讲也是一种DSL。DSL有内部DSL和外部DSL之分。
- 内部DSL
内部DSL指的是与项目中使用的通用目的语言(java,C#等)紧密相关的一类DSL。它基于通用编程语言来实现。 - 外部DSL
内部DSL是利用编程语言的语法结构定义出来的DSL。也叫做内嵌DSL。外部DSL是从零开始构建的语言。需要实现语法分析器等,通常情况下,我们只需要实现内嵌式DSL。因为它更容易构建。并具有很多与外部DSL相同的优势。外部DSL与通用编程语言GPL类似,但是外部DSL更加专注于特定领域。它可以是编译型或者解释型。
Kotlin的DSL特性支持
- 许多现代语言为创建内部DSL提供了一些先进的方法,Kotlin也不例外。在Kotlin中创建DSL,一般需要下面三个特性:
- 扩展函数、扩展属性;
- 带接受者的Lambda表达式(高阶函数);
- invoke函数调用约定
关于扩展函数和高阶函数之前的博客已经说过。下面讲一下Kotlin中的invoke操作符函数。
在集合类中,我么知道Kotlin使用下标运算符foo[x]来等价调用foo.get(x)操作符函数,同样的关于invoke也有一个类似的预订。对一个predicate:(T)->Boolean,可以直接调用predicate(element),如List的扩展函数filterTo中
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {for (element in this) if (predicate(element)) destination.add(element)return destination
}
Kotlin中foo.invoke()可以写成foo(),在Kotlin中操作符是可以重载的,“()”操作符对应的就是类的重载操作函数invoke,即predicate:(T)->Boolean函数调用
prediacate(element) 等价于 predicate.invoke(element)
上面是函数类型对象invoke函数的例子,而实际上在Kotlin中类的对象中也可以直接使用()操作符来调用这个类的invoke操作符函数。下面是一个例子
class Hello {operator fun invoke(name: String) {println("Hello,$name")}}
@JvmStatic
fun main(args: Array<String>) {val hello = Hello()hello.invoke("aaaaa")hello("AAAAA")
}
hello.invoke(“aaaaa”) 、 hello(“AAAAA”) 这两句代都可以正确打印。
实现集合类的流式Kotlin DSL
java的工具类如java.util.Collections,这样的类里面提供了很多静态方法。如:
public static <T> boolean addAll(Collection<? super T> c, T... elements) {boolean result = false;for (T element : elements)result |= c.add(element);return result;
}public static void reverse(List<?> list) {//....
}
实际编码中,通常这样调用这些静态方法。
Collections.reverse(list);
Collections.sort(list);
int index = Collections.binarySearch(list,x);
这样调用看起来不算太漂亮,如果我们希望这样调用代码:
list.sort();
list.reverse();
这就是Kotlin中的扩展函数。
fun <T : Comparable<T>> List<T>.sort() {Collections.sort(this)
}
有了扩展函数,我们就可以开始流式API 的DSL了。代码风格是下面这样的
fun main(args: Array<String>) {val lines ="src/main/resource/data.txt".stream().buffered().reader("utf-8").readLines()lines.forEach(::println)}
- 首先给String类型扩展一个stream()函数:
fun String.stream() = FileInputStream(this)
- 然后给FileInputStream扩展一个bufferrd()函数
fun InputStream.buffered() = BufferedInputStream(this)
- 再给InputStream扩展一个reader(charset:String)函数
fun InputStream.reader(charset :String) = InputStreamReader(this,charset)
- 再给Reader扩展一个readLines()函数
fun Reader.readLines(): List<String> {val result = arrayListOf<String>()forEachLine { result.add(it) }return result
}
有了这些扩展函数,就可以使用开始的流式API。实际上Kotlin中的I/O文件读写及集合类中的流式API就是这么扩展Java。
Kotlin创建DSL相关推荐
- 《Kotlin 程序设计》第十一章 Kotlin实现DSL
第十一章 Kotlin实现DSL 正式上架:<Kotlin极简教程>Official on shelves: Kotlin Programming minimalist tutorial ...
- kotlin创建静态单利_Kotlin程序来计算单利
kotlin创建静态单利 Given, principal, rate, and time, we have to calculate the simple interest. 给定本金,利率和时间, ...
- 为什么awt_为AWT的机器人创建DSL
为什么awt Java SDK附带了java.awt.Robot类,该类允许键盘和鼠标输入的自动化以及屏幕捕获的创建. 当您要编写一个模拟用户输入的小型测试应用程序时,或者只想自动化一些重复文本的输入 ...
- 为AWT的机器人创建DSL
Java SDK附带了java.awt.Robot类,该类允许键盘和鼠标输入的自动化以及屏幕捕获的创建. 如果您想编写一个模拟用户输入的小型测试应用程序,或者只想自动化一些重复文本的输入,则此功能非常 ...
- 出现身份验证错误 要求的函数不受支持_学习使用Kotlin创建Android应用程序第3部分:身份验证登录...
在上一篇文章中,我们讨论了学习Kotlin制作Android应用程序的初学者第2部分:创建登录表单.这次我们来学习创建登录表单后,我们将尝试对上一篇创建的登录表单使用Firebase身份验证.因此,我 ...
- Android中Kotlin创建PDF
一.创建 PDF 流程 首先看官网的文档,下面介绍基于 SDK 怎么样来创建 PDF 文件的流程. //先创建一个 PdfDocument 对象 documentPdfDocument documen ...
- Kotlin Weekly 中文周报 —— 16
Kotlin 开发中文周报 文章 Android 开发者的一些实用技巧.(github.com) Ravindra 在 DevfestAhm 2017 的演讲. 像 Kotlin 的专家一样测试 .( ...
- 《Kotin 极简教程》第13章 使用 Kotlin 和 Anko 的Android 开发
第13章 使用 Kotlin 和 Anko 的Android 开发 最新上架!!!< Kotlin极简教程> 陈光剑 (机械工业出版社) 可直接打开京东,淘宝,当当===> 搜索: ...
- 《Kotlin 极简教程》第13章 使用 Kotlin 和 Anko 的Android 开发
2019独角兽企业重金招聘Python工程师标准>>> 第13章 使用 Kotlin 和 Anko 的Android 开发 13.1 什么是 Anko? Anko (https:// ...
最新文章
- Android开发笔记——常见BUG类型之内存泄露与线程安全
- Design Pattern - Service Locator Pattern--转载
- hdu 5424(dfs搜索)
- 浏览器登录_经常用浏览器自动登录忘记了密码?教你一键查看网页星号密码
- ASP.NET判断是否为手机登录
- linux上mysql定时备份数据库数据_Linux下如何实现MySQL数据库每天定时自动备份
- 课程笔记:深度学习与人类语言处理 ——李宏毅,2020 (P5)
- 【运动学】基于matlab质点极坐标系中运动规律(螺旋运动)【含Matlab源码 977期】
- flash游戏转换html5,一键转换——介绍我做的flash转html5工具LavaH
- 电气工程师需掌握哪些计算机知识,一名合格电气工程师必须掌握的10个基本技能...
- NetSetMan Pro(ip快速切换工具)官方中文版V5.1.0 | 电脑ip切换软件下载
- 计算机基础知识试题和答案
- 重庆万州公交车坠江原因公布:乘客与司机激烈争执互殴致车辆失控
- gophp解释器_golang底层用什么语言实现的
- 拼多多商品APi、商品详情、产品页面信息接口
- 欠定的三元一次方程组求解
- 液晶面板里面有些什么配件_液晶电视核心部件各类液晶面板介绍是什么?请生意经的朋友帮忙解答...
- “外卖”----隐形非物质文化遗产
- 最新免费dede采集方法大全
- 下载echarts地图资源包