Kotlin DSL 基础知识

224 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情

如果您是一名使用 Kotlin 语言开发 Android 的程序员,您可能有意或无意地使用了 DSL。

基本上是 DSL,为特定应用领域创建的计算机语言。

我们使用 DSL 的目的是使代码更具可读性和简单性。我将分享我如何在我的项目中创建一个简单的 DSL。您可以通过更复杂的示例使其更有用。天空才是极限。

我有一个库,需要从外部设置一些参数。

我有一个模型类如下。

data class User(
    val log: Log, 
    val location: Location,
    val number: String
)

data class Log(
    val key: String,
    val value: String
)

data class Location(
    val lat: String,
    val long: String
)

Kotlin DSL 的外观如何

val user = user {
        log = log {
            key { "key" }
            value { "这是一个值" }
        }

        location = location {
            lat { "37.37" }
            long { "37.37" }
        }

        number { "123" }
    }

首先是 DSL 入口点的用户。用户函数将 lambda 作为参数。

用户函数签名的样子:

fun user(lambda: User.() -> Unit) : User

此函数接受将在User类的上下文中运行的 lambda 表达式。

fun user(lambda: User.() -> Unit): User {
    val user = User()
    user.apply(lambda)
    return user
}

在这里完成的简单事情是创建一个 User 类,然后应用给定的 lambda 并返回类型的接收器。

data class User(
    var log: Log? = null,
    var location: Location? = null,
    var number: String = ""
) {
    fun number(lambda: () -> String) {
        this.number = lambda()
    }
}

对于 Log & Location 类,如下所示:

data class Log(
    var key: String = "",
    var value: String = ""
) {
    fun key(lambda: () -> String) {
        this.key = lambda()
    }

    fun value(lambda: () -> String) {
        this.value = lambda()
    }
}
data class Location(
    var lat: String = "",
    var long: String = ""
) {
    fun lat(lambda: () -> String) {
        this.lat = lambda()
    }

    fun long(lambda: () -> String) {
        this.long = lambda()
    }
}

以及日志和定位功能

fun log(lambda: Log.() -> Unit): Log {
    val log = Log()
    log.apply(lambda)
    return log
}
fun location(lambda: Location.() -> Unit): Location {
    val location = Location()
    location.apply(lambda)
    return location
}

我们已经构建了我们的第一个 Kotlin DSL。最后我们可以像这样创建用户类。

val user = user {
        log = log {
            key { "key" }
            value { "这是一个值" }
        }

        location = location {
            lat { "37.37" }
            long { "37.37" }
        }

        number { "123" }
    }

    println(user.number)

就这样

直到下一次,让我们编写更具可读性的代码。

您认为使用 lambda 函数编写 Kotlin DSL 的好方法是好方法吗?