簡介
想要了解Kotlin DSL可以參考這個(gè)文章:Kotlin 之美—DSL篇
內(nèi)網(wǎng)ata也有這樣一篇文章:https://www.atatech.org/articles/138936
KotlinDSL是什么把敞?能用來干什么锹锰?都可以從這兩篇文章中獲得答案嚷往。
而最近谷歌現(xiàn)在也在推Kotlin DSL來替代groovy作為gradle的語言。其實(shí)Kotlin設(shè)計(jì)的思路上主要受到了同為JVM語言的groovy取刃、Scala影響,因此很多用法和寫法都很相似。而Kotlin DSL雷激, 則把 Kotlin 的語法糖演繹得淋漓盡致。學(xué)習(xí)Kotlin DSL可以幫助更好的理解Kotlin中的各種語法告私,用Kotlin DSL來模擬gradle的構(gòu)建過程屎暇,則既可以學(xué)習(xí)Kotlin DSL,又復(fù)習(xí)下gradle的構(gòu)建驻粟。
示例
首先看代碼:
apply("android")
task {
println("debug task run")
}
task("test") {
println("test task run")
doFirst {
println("test task do first")
}
doLast {
println("test task do last")
}
}
dependencies {
compile("com.test.a")
implementation("com.test.b")
}
對(duì)于安卓開發(fā)者來說根悼,這段代碼會(huì)顯得很熟悉,很像gradle中的配置蜀撑,但有一些不同挤巡。但其實(shí),這段代碼并不是groovy屯掖,而是kotlin實(shí)現(xiàn)的代碼玄柏,甚至這段代碼并不是真正的gradle配置,而是我通過kotlin實(shí)現(xiàn)的一段mock gradle代碼贴铜,這里面調(diào)用的所有方法都是調(diào)用了我自己實(shí)現(xiàn)的函數(shù)粪摘。代碼鏈接 奉上瀑晒,可以參考其中的方法實(shí)現(xiàn)。這段代碼的運(yùn)行結(jié)果是這樣的:
---------------- project initialization ----------------
running in context: mock jvm
---------------- project configuration ----------------
abctest
apply plugin: java
debug task run
test task run
add compile dependency: com.test.a
add implementation dependency: com.test.b
---------------- project execution ----------------
configure dependency: com.test.a
configure dependency: com.test.b
execute task:
start executing...
executing task
execute task: test
start executing...
test task do first
executing task
test task do last
從輸出結(jié)果來看徘意,基本mock了gradle的三個(gè)步驟噪伊,有興趣的同學(xué)可以對(duì)照gradle的構(gòu)建流程理解一下奏寨,這里不做詳細(xì)的介紹蒜埋。
而通過這個(gè)示例可以看到挖藏,Kotlin DSL相比原API式的調(diào)用,結(jié)構(gòu)更加清晰勤讽、更接近自然語言的風(fēng)格蟋座。
實(shí)現(xiàn)細(xì)節(jié)
如何去實(shí)現(xiàn)這樣一個(gè)接近自然語言的kotlin dsl?具體可以參考源碼中的Project.kt, 下面介紹幾個(gè)用的比較多的語言特性脚牍,包括:
- 帶Receiver的lambda語句向臀;
這種高階函數(shù)的聲明方式賦予了lambda類似作用域一樣的空間,代碼示例:
// 聲明接收者
fun kotlinDSL(block:StringBuilder.()->Unit){
block(StringBuilder("Kotlin"))
}
// 調(diào)用高階函數(shù)
kotlinDSL {
// 這個(gè) lambda 的接收者類型為StringBuilder
append(" DSL")
println(this)
}
- 中綴調(diào)用诸狭;
在Kotlin中如果函數(shù)的參數(shù)只有一個(gè)券膀,可以使用infix關(guān)鍵字來支持中綴調(diào)用。這種語法的支持讓我們的代碼從函數(shù)調(diào)用更加像自然語言驯遇,代碼示例:
"key" to "value"
// 等價(jià)于
"key.to("value")
// to的聲明芹彬,重點(diǎn)在infix關(guān)鍵字
infix fun Any.to(that:Any) = Pair(this,that)
- invoke約定操作符重載;
這種語法可以讓你像調(diào)用函數(shù)一樣調(diào)用對(duì)象叉庐,代碼示例:
class Person(val name:String){
operator fun invoke(){
println("my name is $name")
}
}
>> val person = Person("geniusmart")
>> person()
my name is geniusmart
除了上面提到的三種語法糖舒帮,還有類似lambda參數(shù)、擴(kuò)展函數(shù)等Kotlin語言特性也在DSL的實(shí)現(xiàn)中得到了使用陡叠,具體可以看代碼会前,相信可以從中體會(huì)到很多Kotlin的妙用。也歡迎大家多多討論更多Kotlin的用法匾竿。