什么是DSL
Domain Special Language
DSL是領(lǐng)域特定語(yǔ)言,與通用語(yǔ)言不通,他只管他的領(lǐng)域,如:SQL、正則表達(dá)式
擴(kuò)展函數(shù)
想理解DSL,首先得知道擴(kuò)展函數(shù)。什么事擴(kuò)展函數(shù),直白一點(diǎn)就是在原有類的基礎(chǔ)上不改變類,只增加一個(gè)函數(shù),稱為擴(kuò)展函數(shù)。
class Test {
fun fun1() {
Test().fun2("fun2")
}
}
fun Test.fun2(name: String) {
}
示例定義Test 類,只有一個(gè)fun1 函數(shù),定義擴(kuò)展函數(shù)fun2,接收一個(gè)String類型參數(shù)
熟悉了擴(kuò)展函數(shù),那就可以寫一個(gè)比較火的代碼生成布局的小例子
class Linear {
fun createFragme(init: (Fragme) -> Unit) {
init(Fragme())
}
fun createText(init: (Text) -> Unit) {
init(Text())
}
}
class Fragme {
fun createText(init: (Text) -> Unit) {
init(Text())
}
}
class Text {}
fun creatLinear(init: (Linear) -> Unit) {
init(Linear())
}
fun run() {
creatLinear {
it.createFragme {
it.createText { }
}
it.createText { }
}
}
偽代碼很好理解,有三種view,其中兩個(gè)是Layout,可以包含其他view。
這樣創(chuàng)建布局是不是很爽,但缺點(diǎn)是調(diào)用函數(shù)要寫 it ,不想寫怎么辦?
答案就是使用DSL
DSL
先看一個(gè)簡(jiǎn)單例子
fun linear(init: Linear.() -> Unit) {
Linear().init()
}
入?yún)⑦€是一個(gè)函數(shù),只不過(guò)這個(gè)函數(shù)前面加上了Linear. 并且去掉了入?yún)?/p>
fun Test.fun2(name: String) {
}
仔細(xì)看 Linear.() 像什么,是不是和上面講的定義擴(kuò)展函數(shù)非常類似,只不過(guò)去掉了函數(shù)名,我們可以叫它 匿名擴(kuò)展函數(shù)。好處就是可以在擴(kuò)展函數(shù)的函數(shù)體中使用this調(diào)用被擴(kuò)展類的函數(shù),而this是可以省略的,從而達(dá)到省略 it 的目的。
簡(jiǎn)單例子中 Linear 叫 接收者類型 , 實(shí)例化的 Linear() 對(duì)象叫接收者對(duì)象
使用DSL 改造上面的例子
class Linear {
fun fragme(init: Fragme.() -> Unit) {
Fragme().init()
}
fun text(init: Text.() -> Unit) {
Text().init()
}
}
class Fragme {
fun text(init: Text.() -> Unit) {
Text().init()
}
}
class Text {}
fun linear(init: Linear.() -> Unit) {
Linear().init()
}
fun run(){
linear {
fragme {
text { }
}
text { }
}
}
是不是清晰了很多