美文网首页Kotlin编程程序员Android技术知识
kotlin 基础 21 DSL(领域特定语言)

kotlin 基础 21 DSL(领域特定语言)

作者: zidea | 来源:发表于2019-04-05 17:06 被阅读5次
    kotlin.jpeg

    什么是 DSL(领域特定语言)呢?

    先说一下他好处吧,就是让更多人更容易地接触到编程,让编程语言更接近人类语言。许多语言在设计之初都在考虑是对人类更友好一些,还是对计算机更用好一些呢。DSL 无疑对人类更友好。可以让更多人加入的 developer 大军中来。

    大家熟悉的 css 和 SQL 语言都是典型的 DSL 语言,我们在写 SQL 语言可能感触很深,感觉自己在写英文语句而非编程语言。

    大家可能注意到了领域,所谓领域也就是限定语言是适用于一定范围的。CSS 专注定义我们页面结构和样式,包括颜色和尺寸等等,而 SQL 专注于对数据的操作。

    DSL 包括两种类型,External 和 Internal

    External 类型,你可以定义规则、定义语法、比较灵活,同时也带来大量的工作,需要自己写解析器。
    Internal,语言本身提供 DSL 特性,无需自己写 parser 造轮子。但是也需要对语言了解熟悉,然后通过现有资源和条件来实现我们 DSL

    context 和 fluency

    context 可以理解为共同语言,那么什么是夫妻间的共同语言呢,简单我们可以谈论都看过电影,我们不需要给出过于详细信息对方也能读懂我们想法,理解彼此意图。

    Mr-and-Mrs-Smith.jpg

    fluency 所谓流畅,就是 DSL 需要更接近人类语法,通过一系列 word 清楚表达一定意思。kotlin 虽然是一门静态语言,但是从他语法和特性来看可以实现一定 fluent。

    kotlin 语言本身特性

    代码结尾分号可省略

    还得说 java 我们必须写 ; 结尾。
    println("hello") 那么回到主题,分号结尾对我们 DSL 有什么影响呢,显而易见影响我们语言的 fluent 流畅性。

    我们可以省略 . 代替用空格。

    class Car{
        fun drive(dist: Int){
            println("driving...")
        }
    }
    
    fun main() {
        val car = Car()
        car.drive(10)
    }
    

    我们这里调用 car 的 drive 方法是通过(.) car.drive(10),我们想写出car drive 10这样看起来更接近人类语言。

    infix fun drive(dist: Int){
            println("driving...")
        }
    

    inflix 告诉编译器多这段代码检查可以放宽松些。

    方法的扩展

    为了提高 DSL 语言的可读性,我们在定义方法名要下一些功夫,但是有些第三方库提供方法名并不能满足 DSL 对 fluent 要求。

    fun main() {
        val car = Car()
        var greeting = "hello"
        fun String.shout() = toUpperCase()
        println(greeting.shout())
    //    car drive 10
    }
    

    toUpperCase 这个方法名显然对 DSL 语言不那么友好,我们需要给他换一个名词来在 DSL 语言中使用。kotlin 又是如何实现的呢?kotlin 并不像其他语言对字节码进行注入,而是通过语法糖包裹来实现,编译器,将 shout 函数接受 String 类型作为参数然后进行重写

    fun process(func:(n:Int) -> Unit, n:Int){
        func(n * 2)
    }
    
    fun List<Tut>.findCoursesGreaterThan(course:Int){
        filter { 
            it.courses > course
        }.forEach(::println)
    }
    
     tuts.findCoursesGreaterThan(60)
    
    Tut(title=rust base, courses=120, author=tina, category=native)
    
    infix fun List<Tut>.findCoursesGreaterThan(course:Int){
        filter {
            it.courses > course
        }.forEach(::println)
    }
    
    tuts findCoursesGreaterThan 60 
    

    相关文章

      网友评论

        本文标题:kotlin 基础 21 DSL(领域特定语言)

        本文链接:https://www.haomeiwen.com/subject/vsghiqtx.html