读书笔记:Kotlin自定义DSL语法

本笔记来自第一行代码第三版第13章,作者郭霖,各大平台均可购买。

前言

DSL的全称时领域特定语言,它是变成语言赋予开发者的一种特殊能力,通过它我们可以编写出一些看似脱离其原始语法结构的代码,从而构建出一种专有的语法结构。

在日常开发中,我们使用DSL语言主要在gradle文件中:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'android.arch.lifecycle:extensions:1.1.1'
    implementation 'androidx.work:work-runtime:2.3.4'
}

为什么这样写,gradle就知道我们到底依赖了哪些库呢?我们在开发中能不能也使用类似的语法呢?在我用Java开发的时候,我觉得这是不太可能的事情,但是现在有了Kotlin,实现这样的语法就轻松多了。

正文

首先创建DSL.kt文件,我们在里面定义Dependency类:

class Dependency {
    val libraries = arrayListOf<String>()

    fun implementation(lib: String) {
        libraries.add(lib)
    }
}

如果是常规用法,我们会这样写:

val dependency = Dependency()
dependency.implementation("lib1")
dependency.implementation("lib2")

如果你再熟悉一点Kotlin,可以优化一下:

val dependency = Dependency().apply{
	implementation("lib1")
	implementation("lib2")
}

目前的代码结构已经很接近DSL语法了,如果我们能把Dependency()的创建隐藏起来就更完美了。

// 自定义高阶函数
fun dependency(block: Dependency.() -> Unit): Dependency{
	val dependency = Dependency()
	dependency.block()
	return dependency 
}
// 用法
val dependency = dependency{
	implementation("lib1")
	implementation("lib2")
}

我们分析一下自定义的高阶函数:

// 表示在方法块中的方法,必须是Dependency类中的,不需要返回值的方法
// 相当于方法块只属于Dependency,等同于apply函数
block: Dependency.() -> Unit

这里需要理解一下,不需要返回值,表示有没有返回值都无所谓,即表示所有的方法通用。但是如果你这样写:

block: Dependency.() -> String

就严格限制了必须返回String类型的方法,使用其他方法就会报错。

总结

DSL语法可有帮助我们节省很多的代码,让代码看上去更规范。本次大部分都是书中的案例,简单明了,下一篇准备使用DSL干点大事。

你可能感兴趣的:(读书笔记,Android)