Kotlin 之 DSL详解

什么是DSL

Domain Special Language
DSL是领域特定语言,与通用语言不通,他只管他的领域,如:SQL、正则表达式

扩展函数

想理解DSL,首先得知道扩展函数。什么事扩展函数,直白一点就是在原有类的基础上不改变类,只增加一个函数,称为扩展函数。

class Test {

    fun fun1() {
        Test().fun2("fun2")
    }


}

fun Test.fun2(name: String) {

}

示例定义Test 类,只有一个fun1 函数,定义扩展函数fun2,接收一个String类型参数

熟悉了扩展函数,那就可以写一个比较火的代码生成布局的小例子


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,其中两个是Layout,可以包含其他view。
这样创建布局是不是很爽,但缺点是调用函数要写 it ,不想写怎么办?
答案就是使用DSL

DSL

先看一个简单例子

fun linear(init: Linear.() -> Unit) {
    Linear().init()
}

入参还是一个函数,只不过这个函数前面加上了Linear. 并且去掉了入参

fun Test.fun2(name: String) {

}

仔细看 Linear.() 像什么,是不是和上面讲的定义扩展函数非常类似,只不过去掉了函数名,我们可以叫它 匿名扩展函数。好处就是可以在扩展函数的函数体中使用this调用被扩展类的函数,而this是可以省略的,从而达到省略 it 的目的。

简单例子中 Linear接收者类型 , 实例化的 Linear() 对象叫接收者对象

使用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 {  }
    }
}

是不是清晰了很多

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容