<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,一般需要下面三个特性:
  1. 扩展函数、扩展属性;
  2. 带接受者的Lambda表达式(高阶函数);
  3. 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)}
  1. 首先给String类型扩展一个stream()函数:
fun String.stream() = FileInputStream(this)
  1. 然后给FileInputStream扩展一个bufferrd()函数
fun InputStream.buffered() = BufferedInputStream(this)
  1. 再给InputStream扩展一个reader(charset:String)函数
fun InputStream.reader(charset :String) = InputStreamReader(this,charset)
  1. 再给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相关推荐

  1. 《Kotlin 程序设计》第十一章 Kotlin实现DSL

    第十一章 Kotlin实现DSL 正式上架:<Kotlin极简教程>Official on shelves: Kotlin Programming minimalist tutorial ...

  2. kotlin创建静态单利_Kotlin程序来计算单利

    kotlin创建静态单利 Given, principal, rate, and time, we have to calculate the simple interest. 给定本金,利率和时间, ...

  3. 为什么awt_为AWT的机器人创建DSL

    为什么awt Java SDK附带了java.awt.Robot类,该类允许键盘和鼠标输入的自动化以及屏幕捕获的创建. 当您要编写一个模拟用户输入的小型测试应用程序时,或者只想自动化一些重复文本的输入 ...

  4. 为AWT的机器人创建DSL

    Java SDK附带了java.awt.Robot类,该类允许键盘和鼠标输入的自动化以及屏幕捕获的创建. 如果您想编写一个模拟用户输入的小型测试应用程序,或者只想自动化一些重复文本的输入,则此功能非常 ...

  5. 出现身份验证错误 要求的函数不受支持_学习使用Kotlin创建Android应用程序第3部分:身份验证登录...

    在上一篇文章中,我们讨论了学习Kotlin制作Android应用程序的初学者第2部分:创建登录表单.这次我们来学习创建登录表单后,我们将尝试对上一篇创建的登录表单使用Firebase身份验证.因此,我 ...

  6. Android中Kotlin创建PDF

    一.创建 PDF 流程 首先看官网的文档,下面介绍基于 SDK 怎么样来创建 PDF 文件的流程. //先创建一个 PdfDocument 对象 documentPdfDocument documen ...

  7. Kotlin Weekly 中文周报 —— 16

    Kotlin 开发中文周报 文章 Android 开发者的一些实用技巧.(github.com) Ravindra 在 DevfestAhm 2017 的演讲. 像 Kotlin 的专家一样测试 .( ...

  8. 《Kotin 极简教程》第13章 使用 Kotlin 和 Anko 的Android 开发

    第13章 使用 Kotlin 和 Anko 的Android 开发 最新上架!!!< Kotlin极简教程> 陈光剑 (机械工业出版社) 可直接打开京东,淘宝,当当===> 搜索: ...

  9. 《Kotlin 极简教程》第13章 使用 Kotlin 和 Anko 的Android 开发

    2019独角兽企业重金招聘Python工程师标准>>> 第13章 使用 Kotlin 和 Anko 的Android 开发 13.1 什么是 Anko? Anko (https:// ...

最新文章

  1. 文件目录管理及vi编辑器的使用
  2. C语言中的位运算符主要有哪些?逻辑右移与算术右移的区别?
  3. 如果你对java的异常处理头皮发麻,那就进来吧
  4. ITK:创建矢量图像
  5. 使用Java流查询数据库
  6. html-css练习题(系统提示)
  7. mysql 8 强制修改密码_Mysql 8.0版本强制无密码进入+更改密码
  8. UIScrollView的几个要点总结
  9. FFT FNT 简要整理
  10. html 语言包,语言包编辑
  11. 基于STM32的红绿灯控制系统设计
  12. RXTX for java在arm上的使用
  13. windows下生成ssh key详解
  14. 【Digger爬虫系列】用Digger抓取taptap游戏排行榜
  15. OpenGL LookAt函数理解
  16. AFEPack 使用 Tutorial(二):解带系数二维泊松方程
  17. 华为遭到英国政府调查。网友: 全世界都在针对华为!
  18. Java面试宝典!java除法保留小数点后两位
  19. 蜀中猿从学oracle,02,时间2015-5-15
  20. 错题本——数据库系统工程师 2010

热门文章

  1. Flutter混合开发框架安装流程(亲测能用)
  2. 马平福书画家专属定制创作收藏级艺术品亮相交大教育集团高净值研究院高峰论坛
  3. PCtoLCD2002完美版使用总结
  4. 这5点措施,将手淘 Crash 率最高下降40%
  5. android item复用,Android RecyclerView 复用错乱通用解法详解
  6. RowMapper接口
  7. web前端-JavaScript中的数组详解
  8. 为什么除了Go语言, 其他类C语言都是垃圾[翻译][转]
  9. 【C语言】你真的了解结构体吗
  10. vue cli创建vue3.0项目步骤