化工网站制作,网站建设资源平台,wordpress4.0友情链接,wordpress 入门主题DSL#xff08;领域特定语言#xff09;
常见的DSL就是SQL和正则表达式#xff0c;用于操作数据库和文本字符串#xff0c;Kotlin DSL通常为嵌套的Lambda表达式或链式方法#xff0c;如
https://github.com/gradle/gradle-script-kotlin 用于构建Gradle脚本https://gith…DSL领域特定语言
常见的DSL就是SQL和正则表达式用于操作数据库和文本字符串Kotlin DSL通常为嵌套的Lambda表达式或链式方法如
https://github.com/gradle/gradle-script-kotlin 用于构建Gradle脚本https://github.com/JetBrains/Exposed 用于操作数据库https://github.com/Kotlin/kotlinx.html 用于生成HTML
带接收者的Lambda和扩展函数类型
对于普通的生成字符串函数需要在Lambda中使用it指向StringBuilder实例
fun buildString(builderAction: (StringBuilder) - Unit): String {val sb StringBuilder()builderAction(sb)return sb.toString()
}val s buildString {it.append(Hello )it.append(World)
}println(s)转换为带接收者的Lambda可通过this或直接调用方法
fun buildString(builderAction: StringBuilder.() - Unit): String {val sb StringBuilder()sb.builderAction()return sb.toString()
}val s buildString {this.append(Hello )append(World)
}println(s)具体做法是使用扩展函数类型取代普通函数类型来声明参数的类型将函数类型签名中的一个参数移到括号前面并用一个.分割
(StringBuilder) - Unit //一个接收StringBuild参数、无返回值的函数
StringBuilder.() - Unit //将接收者对象参数往前移也声明一个扩展函数类型的变量
val appendExcl: StringBuilder.() - Unit { this.append(!) }
val sb StringBuilder(Hi)
sb.appendExcl()
println(sb)Kotlin标准库中的apply和with就是利用扩展函数类型
public inline fun T T.apply(block: T.() - Unit): T {.....block() //apply的接收者被当作lambda的接收者return this //返回接收者
}public inline fun T, R with(receiver: T, block: T.() - R): R {......return receiver.block() //返回调用Lambda的结果
}HTML构建器
用于Html的Kotlin DSL叫做HTML构建器其是类型安全的
open class Tag(val name: String) {private val children mutableListOfTag()protected fun T : Tag doInit(child: T, init: T.() - Unit) {child.init()children.add(child)}override fun toString() $name${children.joinToString()}/$name
}fun table(init: TABLE.() - Unit) TABLE().apply(init)class TABLE : Tag(table) {fun tr(init: TR.() - Unit) doInit(TR(), init)
}class TR : Tag(tr) {fun td(init: TD.() - Unit) doInit(TD(), init)
}class TD : Tag(td)fun createTable() table {tr {td {}}}调用
println(createTable())tabletrtd/td/tr/tableinvoke约定
重写invoke()可以让对象像函数一样调用p(1)会被编译成p.invoke(1)
class Person(val name: String) {operator fun invoke(age: Int) {println($name,$age)}
}val p Person(A)
p(1)Gradle中的DSL
class DependencyHandler {fun compile(coordinate: String) {println(add dependency on $coordinate)}operator fun invoke(body: DependencyHandler.() - Unit) {body()}
}val dependencies DependencyHandler()dependencies.compile(com.demo.demo-lib:1.0.0)dependencies {compile(com.demo.demo-lib:1.0.0)
}中缀调用的DSL
对于下面的DSL
infix fun T T.should(matcher: MatcherT) matcher.test(this)interface MatcherT {fun test(value: T)
}class startWith(val prefix: String) : MatcherString {override fun test(value: String) {if (!value.startsWith(prefix)) {throw AssertionError($value does not start with $prefix)}}可使用中缀调用
kotlin should startWith(kot)kotlin.should(startWith(kot))还可利用包装类进一步简化利用obetject对象选择不同类型的should()重载方法
object start
infix fun String.should(x: start): StartWrapper StartWrapper(this)
class StartWrapper(val value: String) {infix fun with(prefix: String) if (!value.startsWith(prefix))throw AssertionError($value does not start with $prefix)elseprintln(success)
}kotlin should start with (kot)kotlin.should(start).with(kot)基本数据类型上定义扩展
val Int.days: Periodget() Period.ofDays(this)val Period.ago: LocalDateget() LocalDate.now() - thisval Period.fromNow: LocalDateget() LocalDate.now() this通过扩展函数实现获取一天前和一天后的日期
println(1.days.ago)
println(1.days.fromNow)