DSL 是什么
DSL 全称是 Domain Specific Language,即领域特定语言。顾名思义 DSL 是用来专门解决某一特定问题的语言,比如我们常见的 SQL 或者正则表达式等,DSL 没有通用编程语言(Java、Kotlin等)那么万能,但是在特定问题的解决上更高效。
创作一套全新新语言的成本很高,所以很多时候我们可以基于已有的通用编程语言打造自己的 DSL,比如日常开发中我们将常见到 gradle 脚本 ,其本质就是来自 Groovy 的一套 DSL:
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.luge.app"
minSdkVersion 24
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
Kotlin DSL 及其优势
Kotlin DSL的好处,尤其是对View进行特定领域的处理的时候 很有用。
- 有着近似 XML 的结构化表现力
- 较少的字符串,更多的强类型,更安全
- 可提取 linearLayoutParams 这样的对象方便复用
- 在布局中同步嵌入 onClick 等事件处理
- 如需要还可以嵌入 if ,for 这样的控制语句
DSL的实现原理
扩展函数(扩展属性)
package strings
fun String.lastChar(): Char = this.get(this.length - 1)
lambda使用
lambda 表达式定义:
高阶函数:高阶函数就是以另一个函数作为参数或返回值的函数。
Kotlin 的 lambda 有个规约:如果 lambda 表达式是函数的最后一个实参,则可以放在括号外面,并且可以省略括号
person.maxBy({ p:Person -> p.age })
// 可以写成
person.maxBy(){
p:Person -> p.age
}
// 更简洁的风格:
person.maxBy{
p:Person -> p.age
}
带接收者的 lambda:
举例说明:
public inline fun String.apply(block:String() -> Unit):String{
block()
return this
}
invoke 约定
invoke约定的作用:它的作用就是让对象像函数一样调用方法
```
class DependencyHandler{
//编译库
fun compile(libString: String){
Logger.d(“add $libString”)
}
//定义invoke方法
operator fun invoke(body: DependencyHandler.() -> Unit){
body()
}
}
//我们有下面的3种调用方式:
val dependency = DependencyHandler()
//调用invoke
dependency.invoke {
compile("androidx.core:core-ktx:1.6.0")
}
//直接调用
dependency.compile("androidx.core:core-ktx:1.6.0")
//带接受者lambda方式
dependency{
compile("androidx.core:core-ktx:1.6.0")
}