第十一章 Kotlin实现DSL

正式上架:《Kotlin极简教程》Official on shelves: Kotlin Programming minimalist tutorial
京东JD:https://item.jd.com/12181725.html
天猫Tmall:https://detail.tmall.com/item.htm?id=558540170670

DSL

DSL 即 domain-specific languages,领域特定语言。和一般的编程语言不同,领域特定语言只能用于特定的领域中并且表现形式有限。领域特定语言最大的功能就是可以让语言本身更容易阅读,方便开发者和领域专家进行交流。

实现 DSL

Java 中 DSL 的最简单实现方式就是构造器模式,而在 Kotlin 过去的版本中可以省略 .,所以可以写成更易读的代码,但是现在的版本已经不支持了。

构造器模式

Machine machine = new Machine.Builder()
.setCore(8)
.setArch("64 bits")
.setOs("Linux")
.build();
DSL 方式

定义必要的类和方法

data class Cpu(val core: Int, val arch: String)

class Machine {
var cpu: Cpu? = null
var os: String? = null

fun having(cores: Int, arch: String): Machine {cpu = Cpu(cores, arch)return this
}fun os(os: String): Machine {this.os = osreturn this
}override fun toString(): String {return "Machine{cpu=$cpu, os='$os'"
}

}
构建对象

val m1 = Machine().having(8, "64 bits").os("linux")
val m2 = Machine().having(4, "32 bits").os("Windows")
可以看到使用 DSL 后代码更加易读。

使用闭包构建 DSL

Kotlin 像 Groovy 一样也能通过闭包构建 DSL,语法看起来很像 Groovy。

定义必要的类和方法

class EmailSpec {
fun from(from: String) = println("From: $from")
fun to(to: String) = println("To: $to")
fun subject(subject: String) = println("Subject: $subject")
fun body(init: BodySpec.() -> Unit): BodySpec {
val body = BodySpec()
body.init()
return body
}
}

class BodySpec {
fun p(p: String) = println("P: $p")
}

fun email(init: EmailSpec.() -> Unit): EmailSpec {
val email = EmailSpec()
email.init()
return email
}
调用 DSL 语句

email {
from ("dsl-guru@mycompany.com")
to ("john.doe@waitaminute.com")
subject ("The pope has resigned!")
body {
p ("Really, the pope has resigned!")
}
}

val data = mapOf(1 to "one", 2 to "two")createHTML().table {//遍历数据for ((num, string) in data) {//创建 HTML 标签的函数tr {td { +"$num" } td { +string }}}
}
/*** This is an example of a Type-Safe Groovy-style Builder** Builders are good for declaratively describing data in your code.* In this example we show how to describe an HTML page in Kotlin.** See this page for details:* http://kotlinlang.org/docs/reference/type-safe-builders.html*/
package htmlfun main(args: Array<String>) {val result =html {head {title { +"XML encoding with Kotlin" }}body {h1 { +"XML encoding with Kotlin" }p { +"this format can be used as an alternative markup to XML" }// an element with attributes and text contenta(href = "http://jetbrains.com/kotlin") { +"Kotlin" }// mixed contentp {+"This is some"b { +"mixed" }+"text. For more see the"a(href = "http://jetbrains.com/kotlin") { +"Kotlin" }+"project"}p { +"some text" }// content generated from command-line argumentsp {+"Command line arguments were:"ul {for (arg in args)li { +arg }}}}}println(result)
}interface Element {fun render(builder: StringBuilder, indent: String)
}class TextElement(val text: String) : Element {override fun render(builder: StringBuilder, indent: String) {builder.append("$indent$text\n")}
}abstract class Tag(val name: String) : Element {val children = arrayListOf<Element>()val attributes = hashMapOf<String, String>()protected fun <T : Element> initTag(tag: T, init: T.() -> Unit): T {tag.init()children.add(tag)return tag}override fun render(builder: StringBuilder, indent: String) {builder.append("$indent<$name${renderAttributes()}>\n")for (c in children) {c.render(builder, indent + "  ")}builder.append("$indent</$name>\n")}private fun renderAttributes(): String? {val builder = StringBuilder()for (a in attributes.keys) {builder.append(" $a=\"${attributes[a]}\"")}return builder.toString()}override fun toString(): String {val builder = StringBuilder()render(builder, "")return builder.toString()}
}abstract class TagWithText(name: String) : Tag(name) {operator fun String.unaryPlus() {children.add(TextElement(this))}
}class HTML() : TagWithText("html") {fun head(init: Head.() -> Unit) = initTag(Head(), init)fun body(init: Body.() -> Unit) = initTag(Body(), init)
}class Head() : TagWithText("head") {fun title(init: Title.() -> Unit) = initTag(Title(), init)
}class Title() : TagWithText("title")abstract class BodyTag(name: String) : TagWithText(name) {fun b(init: B.() -> Unit) = initTag(B(), init)fun p(init: P.() -> Unit) = initTag(P(), init)fun h1(init: H1.() -> Unit) = initTag(H1(), init)fun ul(init: UL.() -> Unit) = initTag(UL(), init)fun a(href: String, init: A.() -> Unit) {val a = initTag(A(), init)a.href = href}
}class Body() : BodyTag("body")
class UL() : BodyTag("ul") {fun li(init: LI.() -> Unit) = initTag(LI(), init)
}class B() : BodyTag("b")
class LI() : BodyTag("li")
class P() : BodyTag("p")
class H1() : BodyTag("h1")class A() : BodyTag("a") {public var href: Stringget() = attributes["href"]!!set(value) {attributes["href"] = value}
}fun html(init: HTML.() -> Unit): HTML {val html = HTML()html.init()return html
}

https://www.kotliner.cn/2017/05/15/2017-5-11-KotlinDSL2/

《Kotlin 程序设计》第十一章 Kotlin实现DSL相关推荐

  1. 《Kotlin 程序设计》第一章 Kotlin简介

    第一章 Kotlin简介 科特林岛(Котлин)是一座俄罗斯的岛屿,位于圣彼得堡以西约30公里处,形状狭长,东西长度约14公里,南北宽度约2公里,面积有16平方公里,扼守俄国进入芬兰湾的水道.科特林 ...

  2. 《Kotlin 程序设计》第二章 快速开始:HelloWorld

    第二章 快速开始:HelloWorld 使用云端在线IDE学习Kotlin 我们不需要搭建任何环境,只要有一台能联网的设备,打开浏览器访问: https://try.kotlinlang.org 你就 ...

  3. 《Kotlin 程序设计》第十二章 Kotlin的多线程:协程(Coroutines)

    第十二章 Kotlin的多线程:协程(Coroutines) Kotlin 1.1 introduced coroutines, a new way of writing asynchronous, ...

  4. 《Kotlin 程序设计》第五章 Kotlin 面向对象编程(OOP)

    第五章 Kotlin 面向对象编程(OOP) 正式上架:<Kotlin极简教程>Official on shelves: Kotlin Programming minimalist tut ...

  5. 《Kotlin项目实战开发》第1章 Kotlin是什么

    第1章 Kotlin是什么 当下互联网大数据云计算时代,数以百万计的应用程序在服务器.移动手机端上运行,其中的开发语言有很大一部分是用流行软件界20多年的.强大稳定的主力的编程语言Java编写. 如果 ...

  6. 第1章 Kotlin是什么

    第1章 Kotlin是什么 当下互联网大数据云计算时代,数以百万计的应用程序在服务器.移动手机端上运行,其中的开发语言有很大一部分是用流行软件界20多年的.强大稳定的主力的编程语言Java编写. 如果 ...

  7. 第3章 Kotlin语言基础 《Kotlin 极简教程》

    2019独角兽企业重金招聘Python工程师标准>>> 第3章 Kotlin语言基础 掌握基础,持续练习 学习任何东西,都是一个由表及里的过程.学习一门编程语言也一样.对于一门编程语 ...

  8. 《Kotlin极简教程》第1章 Kotlin简介

    第1章 Kotlin简介 最新上架!!!< Kotlin极简教程> 陈光剑 (机械工业出版社) 可直接打开京东,淘宝,当当===> 搜索: Kotlin 极简教程 http://ww ...

  9. 第13章 Kotlin 集成 SpringBoot 服务端开发(1)

    第13章 Kotlin 集成 SpringBoot 服务端开发 本章介绍Kotlin服务端开发的相关内容.首先,我们简单介绍一下Spring Boot服务端开发框架,快速给出一个 Restful He ...

最新文章

  1. python 列表筛选数据
  2. 1111B - Average Superhero Gang Power
  3. HTML5标签的语义认知和理解
  4. 启动之OS_CPU_C
  5. java javap_javap的用途不断发展:您的Java类文件中隐藏了什么?
  6. 论文浅尝 - AAAI2020 | 通过句子级语义匹配和答案位置推断改善问题生成
  7. [物理学与PDEs]第3章第3节 电导率 $\sigma$ 为无穷时的磁流体力学方程组 3.3 磁场线``冻结''原理...
  8. tcp码流中查找rtp头_跟踪数据流中的时间以查找性能问题
  9. ubuntu安装rpm的方法
  10. leetcode 【 Sort Colors 】python 实现
  11. IT小公司避坑及生存指南
  12. 指纹调试 mtk(MT6763)- android8.1
  13. 当初我要是这么学习操作系统就好了(附带思维导图)
  14. 网络安全与网站安全及计算机安全:如何下载到Windows各版本的Nmap网络扫描神器
  15. Moles(笛卡尔树 Z Algorithm)
  16. c 语言 控制台程序 行字体颜色,C# 控制台程序设置字体颜色
  17. 推荐一个牛逼的直播开源项目
  18. 智工教育:一级建造师《公路实务》考前必背知识点
  19. Stealth-Persist混合内存系统中持久应用程序的体系结构支持
  20. 虚拟化系统到VMware虚拟机

热门文章

  1. 数塔 简单的 动态规划
  2. 用C#把文件转换为XML
  3. 苹果决定不修复 Big Sur 和 Catalina 中的这两个0day
  4. 古早但有用:CISA 发布15个正遭利用的老旧漏洞
  5. 三年蜜罐实验:黑客想从物联网设备中得到什么?
  6. Google Maps 补丁绕过、得双倍奖金这么简单?我陷入了自我怀疑
  7. K8S认证、授权与准入控制(RBAC)详解
  8. SuperTuxKart 0.10 测试版发布
  9. 14.12.1类的特殊成员1
  10. 英国Just Eat自动驾驶机器人的外卖系统上线