Kotlin 使用DSL构建语法结构 看这一篇就够了~

简介: Kotlin 使用DSL构建语法结构 看这一篇就够了~

前言

DSL并不是单独为Kotlin语言提供的,可能你并知道DSL是什么,但是我敢说,只要你是Android开发者,你就一定使用过并且一直在使用DSL,那么到底什么是DSL?使用DSL又可以实现怎么样的功能呢?

image.gif

DSL是什么

DSL的全程是Domain Specific Language 即 领域特定语言,我们可以通过DSL语言 构建出属于我们自己的语法结构,而在Kotlin中并不只有一种方式实现DSL,而主要的实现方式就是高阶函数(如果你不了解高阶函数,也不用怕,后面我会单独一篇文章来介绍高阶函数)~

我是Android开发者,我怎么没用过DSL,我阿黄哥不信!

想想看,平时我们引入一个开源包需要怎么做呢,我们会在build.gradle中看到这样的代码:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.core:core-ktx:1.3.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

image.gif

Gradle 我们都知道 它是一种基于Groovy的构建工具,上面的代码写法其实是Groovy为我们提供的DSL功能。

image.gif

DSL的基础用法

接下来,我们来看,Kotlin中如何使用DSL构建自己的语法呢,要想装13 我们当然要来实现和上面一样的语法结构,那我们就来造一个吧~

首先我们新建一个类Dependency,名字是可以随便起的,只不过我们为了装13,就取的和我们经常使用的一样,声明一个list数组,为list提供添加的数据的方法,类代码如下所示:

class Dependency {
    var libs = mutableListOf<String>()
    fun implementation(lib: String) {
        libs.add(lib)
    }
}

image.gif

接着,我们定义一个高阶函数,参数是Dependency的扩展函数

fun dependencies(block: Dependency.() -> Unit): List<String> {
    val dependency = Dependency()
    dependency.block()
    return dependency.libs
}

image.gif

上面的代码,只要你了解高阶函数,肯定可以看得懂,高阶函数中的参数是Dependency的扩展函数,所以我们要先初始化一个Dependency,通过实例调用参数,就可以执行传入的Lambda表达式了,我们新建一个Test.kt,在main方法中使用如下:

dependencies {
        implementation("com.huanglinqing.ll")
        implementation("com.huanglinqing.hh")
    }

image.gif

怎么样,和我们在build.gradle 使用的方法很像吧

image.gif

           

因为我们定义的方法,返回的是List,所以我们可以将结果打印出来,代码如下所示:

var list = dependencies {
        implementation("com.huanglinqing.ll")
        implementation("com.huanglinqing.hh")
    }
    for (text in list) {
       println("$text")
    }

image.gif

再次运行程序,结果如下所示:

com.huanglinqing.ll
com.huanglinqing.hh
Process finished with exit code 0

image.gif

DSL 还可以怎么用

DSL 可以将符合标准API规范的代码转化为符合人类理解的自然语言

image.gif

我们以创建一个用户对象为例,新建User.kt,为了方便打印 我们重写toString方法,代码如下所示:

data class User(var name: String = "", var age: Int = 0) {
    override fun toString(): String {
        return "My name is $name ,i am $age years old"
    }
}

image.gif

我们仍然在Test.kt中写测试代码,来看下按照API规范我们如何来创建一个User对象

val user = User("Huanglinqing", 25)
    println(user)

image.gif

运行结果如下所示:

My name is Huanglinqing ,i am 25 years old
Process finished with exit code 0

image.gif

那么,我们如何使用DSL的方式去创建一个User对象呢,首先我们需要提供一个高阶函数

fun create(block: User.() -> Unit): User {
    var user = User()
    block(user)
    return user
}

image.gif

我们定义了一个类型为User扩展函数的高阶函数,通过block调用表达式的部分

所以我们可以直接这样来创建一个User对象:

val user1 = create {
    name = "黄林晴"
    age = 25
}
println(user1)

image.gif

我们称这种方式是更符合理解的方式,运行结果与上面一致,这里就不再演示了。

Anko插件

最后我们来简单的介绍下DSL在Kotlin中的一个框架Anko,Anko用Kotlin DSL 写的Android插件,Anko主要的作用是替代以前用XML的方式来生成UI布局。不过Jetpack推出了compose,虽然还没有正式版本,但是用的也比较多了,很多人都不了解说为什么要推荐在Activity中写布局代码 就像Flutter一样?大家都知道,Android界面是通过XML来进行布局的,一个应用中通常有多个布局,当程序运行时,XML被转化为Java代码,这里要划重点,即使不是在Java中写的代码,最终还是会转化为Java代码,这就会导致程序很耗费资源。由于Anko是直接通过Java代码来编写布局文件的,不用进行转化,因此使用Anko编写Android界面的布局会更加简单、快捷。所以我猜测,这也许为什么Jetpack要推出compose的原因之一吧。

关于Anko插件如何使用,就不讲解了,感兴趣的可直接到Github上了解:https://github.com/Kotlin/anko

写在最后

DSL的使用场景远远不止这些,其实前提就是使用好高阶函数,很多例子都讲到了使用DSL来生成HTML的代码,不过在业务中没get到他的作用,想了解的朋友可以私下和我沟通。其实不管任何一种技术,一个框架,我们不能评判他的好坏,存在即合理,推动项目开展才是王道。好了 ,DSL的基础了解就到这里了,快去愉快的装13吧~

目录
相关文章
|
1月前
|
前端开发 JavaScript 测试技术
Kotlin教程笔记 - 适合构建中大型项目的架构模式全面对比
Kotlin教程笔记 - 适合构建中大型项目的架构模式全面对比
31 3
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
本系列教程笔记详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。若需快速学习Kotlin,建议查看“简洁”系列教程。本期重点介绍了Kotlin与Java的共存方式,包括属性、单例对象、默认参数方法、包方法、扩展方法以及内部类和成员的互操作性。通过这些内容,帮助你在项目中更好地结合使用这两种语言。
51 1
|
2月前
|
Java 开发工具 Android开发
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
Kotlin语法笔记(26) -Kotlin 与 Java 共存(1)
35 2
|
1天前
|
数据采集 安全 API
高级技术文章:使用 Kotlin 和 Unirest 构建高效的 Facebook 图像爬虫
高级技术文章:使用 Kotlin 和 Unirest 构建高效的 Facebook 图像爬虫
|
1月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
44 1
|
2月前
|
IDE 开发工具 数据安全/隐私保护
Kotlin语法 - 类成员
本教程详细讲解Kotlin语法,适合深入学习。若需快速掌握,推荐“简洁”系列教程。内容涵盖类成员、函数与方法、属性访问控制及初始化等。类成员包括方法和属性,函数独立于类,属性访问通过getter/setter实现,支持延迟初始化。
43 3
|
2月前
|
数据安全/隐私保护 Kotlin
Kotlin语法 - 类成员
Kotlin语法 - 类成员
|
2月前
|
Java 编译器 Android开发
Kotlin语法笔记(28) -Kotlin 与 Java 混编
本系列教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文档重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android library开发建议以及在Kotlin和Java之间互相调用的方法。
33 1