Kotlin DSL 入门

这一章咱们聊聊 Kotlin DSL。说白了,就是让你用 Kotlin 写 Gradle 脚本。

很多同学问:我 Groovy 用得挺顺,干嘛非要换 Kotlin?我个人习惯先用 Kotlin 写新项目,因为它的类型安全能帮我提前发现好多坑。以前用 Groovy 写 dependencies 时敲错个引号,编译时才报错,定位半天。换成 Kotlin 后,IDE 直接红线提示,省心不少。

选 Kotlin 还是 Groovy?

直接给结论:新项目我建议用 Kotlin DSL。为啥?

  • 类型安全:变量、函数签名、闭包参数都有明确类型,IDE 补全更准。
  • 性能更好:Kotlin 脚本预编译后,增量构建比 Groovy 快不少。
  • 调试方便:堆栈信息清晰,不用猜那个字符串到底是啥类型。

当然 Groovy 也有优势——灵活,适合快速原型。但团队协作项目里,灵活 = 容易乱。我在一个老项目里见过 Groovy 脚本里动态注入一堆 extra 属性,后来谁都不敢改。所以,除非你维护的是已有 Groovy 项目,否则选 Kotlin。

对比项 Groovy DSL Kotlin DSL
类型检查 运行时 编译时
IDE 支持 一般 强(自动补全、重构)
学习成本 低 中等(需懂 Kotlin 基础)
脚本缓存 慢 快(预编译)

⚠️ 避坑:千万不要在同一个项目中混用 .gradle 和 .gradle.kts 文件。我曾经尝试把部分模块切到 Kotlin,结果 Gradle 配置缓存冲突,搞了一下午才排查出来。

Kotlin 语法核心——够用就行

不用把整本 Kotlin 书啃完。你只需要掌握这几个点:

  1. 变量声明:val 不可变,var 可变。Gradle 脚本里多用 val。
  2. Lambda 表达式:{ param -> body },Gradle 闭包的本质就是 lambda。
  3. 扩展函数:比如 configurations { ... } 其实就是在 ConfigurationContainer 上调用扩展。
  4. 类型推断:IDE 能帮你推导,但写清楚类型更安全。

举个例子,以前 Groovy 这么写依赖:

dependencies {
    compile 'com.google.guava:guava:30.0-jre'
}

换成 Kotlin:

dependencies {
    implementation("com.google.guava:guava:30.0-jre")
}

你看,函数调用用圆括号,参数之间用逗号。Groovy 里省略括号和字符串引号,Kotlin 必须写全。刚开始可能会不习惯,但好处是——不会因为少个引号导致怪异错误。

💡 技巧:在 IntelliJ IDEA 里新建 .gradle.kts 文件时,它会提示你是否自动转换。我一般先写个简单的 println("hello") 验证脚本能跑,再加逻辑。

在 Gradle 中使用 Kotlin 脚本

把 build.gradle 改成 build.gradle.kts,Gradle 会自动识别为 Kotlin DSL。注意文件名必须严格全小写,不要写成 Build.gradle.kts。

常见的配置长这样:

// build.gradle.kts
plugins {
    java
    application
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.google.guava:guava:30.0-jre")
    testImplementation("org.junit.jupiter:junit-jupiter:5.7.1")
}

tasks.test {
    useJUnitPlatform()
}

application {
    mainClass.set("com.example.Main")
}

注意几个变化:

  • plugins 块里直接用 java 而不是 id 'java'。
  • repositories 不再需要 mavenCentral() 的引号,它是个函数调用。
  • 任务的配置用 lambda 表达式,比如 tasks.test { ... }。

如果你是多模块项目,settings.gradle.kts 也要改:

rootProject.name = "my-project"
include(":app", ":lib")

这里 include 是用可变参数,不需要 [] 包裹。

🔑 核心:Kotlin 脚本里所有东西都是强类型的。你调用 dependencies { } 时,编辑器会告诉你这个 lambda 的接收者类型是 DependencyHandler,然后你就可以用它的函数 implementation()、testImplementation() 等。一旦你习惯了,写起来比 Groovy 还快——因为 IDE 会直接弹出提示。

对了,记得把 gradle-wrapper.properties 里的 Gradle 版本升级到 6.8 以上,对 Kotlin DSL 支持更好。

本章知识结构

下面这张图梳理了从选择到落地的完整路线:

Kotlin DSL 入门知识结构 DSL 选择 Kotlin DSL Groovy DSL Kotlin 语法核心 val/var · Lambda · 扩展函数 Gradle Kotlin 脚本 build.gradle.kts settings.gradle.kts 执行 & 调试 💡 IDE 自动补全 + 预编译缓存 Kotlin 路线 传统 Groovy 路线

从图里能看到:左边的 Kotlin 路线经过语法学习,最终落地到实际脚本文件,而 Groovy 路线则相对孤立(除非你维护老项目,否则不建议深入)。

最后提醒一点:初次转化时不要一次改完所有模块。我会先在根项目改成 settings.gradle.kts,跑通一个 build.gradle.kts,再逐步迁移子模块。嗯,稳扎稳打才靠谱。