Kotlin 2.3.20 发布!解构声明不怕写反了

kotlin 复制代码
val (email, username) = user

你确定没写反?

如果 User 的属性顺序是 (username, email),恭喜你,这段代码已经悄悄埋了一个 bug。更可怕的是,两个属性都是 String 类型,编译器不会报任何错误。

Kotlin 2.3.20 刚刚发布,最大的亮点就是:解构声明终于支持按名称匹配了。

这个被社区呼吁了多年的特性,终于落地。

Position-Based:一个沉默的陷阱

Kotlin 的 data class 解构声明,一直以来都是按位置匹配的。编译器在背后生成 component1()component2() 这样的函数,变量按顺序绑定。

kotlin 复制代码
data class User(val username: String, val email: String)

val (first, second) = user
// first = username (component1)
// second = email (component2)

属性少的时候还好。但一旦属性多了,或者属性类型相同,就变成了定时炸弹。

想象一下:你的同事重构了 User,把 email 提到了第一个参数。你项目里所有的 val (username, email) = user 全部静悄悄地交换了值。

没有编译错误,没有运行时异常,只有一个"为什么用户收到的邮件称呼变成了邮箱地址"的线上 bug。

Name-Based Destructuring 来了

Kotlin 2.3.20 引入了基于名称的解构声明。变量不再按位置绑定,而是按名称匹配属性。

完整形式的语法长这样:

kotlin 复制代码
val (name = username, mail = email) = user
// name 绑定到 username 属性
// mail 绑定到 email 属性
// 顺序无关!

等号左边是你定义的局部变量名,右边是要匹配的属性名。顺序不再重要。

如果你的局部变量名和属性名一致,还有更简洁的写法(需要开启 complete 模式):

kotlin 复制代码
val (email, username) = user
// 自动按名称匹配,不再按位置

而如果你确实需要按位置匹配,改用方括号:

kotlin 复制代码
val [first, second] = user
// 方括号 = 位置匹配(component1, component2)

圆括号按名称,方括号按位置。语义清晰,不再模糊。

怎么启用

目前提供了三种渐进模式,在 build.gradle.kts 中配置:

kotlin 复制代码
kotlin {
    compilerOptions {
        freeCompilerArgs.add(
            "-Xname-based-destructuring=name-mismatch"
        )
    }
}

三种模式的区别:

  • only-syntax :仅启用显式的完整形式 val (a = propName) = obj
  • name-mismatch:变量名和属性名不匹配时发出警告(推荐先用这个)
  • complete :完全启用,短形式 () 按名称匹配,位置匹配改用 []

建议从 name-mismatch 开始。让编译器帮你排查现有代码中潜在的问题,再逐步迁移到 complete

JPA 开发者的福音

用 Kotlin 写 JPA 实体类的同学,一定踩过这个坑:Kotlin 的 class 默认是 final 的,而 JPA 的懒加载需要生成代理类,代理类要求实体类必须是 open 的。

以前你得手动配置两个插件:

kotlin 复制代码
// Before: 要写一堆配置
plugins {
    kotlin("plugin.jpa")
    kotlin("plugin.allopen")  // 还得额外加这个
}

allOpen {
    annotation("jakarta.persistence.Entity")
    annotation("jakarta.persistence.Embeddable")
    annotation("jakarta.persistence.MappedSuperclass")
}

Kotlin 2.3.20 之后,plugin.jpa 自动搞定一切:

kotlin 复制代码
// After: 一行搞定
plugins {
    kotlin("plugin.jpa")
}
// all-open 自动应用,JPA 注解预设内置

同时支持 javax.persistencejakarta.persistence。Maven 用户同样受益------kotlin-maven-noarg 现在隐式包含了 kotlin-maven-allopen

Kotlin/Wasm 性能起飞

如果你在关注 Kotlin Multiplatform 的 Web 端,这个版本的 Wasm 目标有了质的飞跃:

  • 字符串插值性能提升最高 4.6 倍
  • 产物体积减小约 5%
  • 全量构建速度提升 65%
  • 增量构建速度提升 21%

这些不是微优化。特别是构建速度------全量构建快了将近两倍,日常开发的体感会非常明显。

此外,新增了 @nativeInvoke 注解,允许 Kotlin 对象在 JavaScript 中直接作为函数调用。

TypeScript 可以实现 Kotlin 接口了

Kotlin/JS 终于支持从 TypeScript 直接实现 Kotlin 接口。这对 KMP 生态来说是一个重要的里程碑。

Kotlin 侧定义并导出接口:

kotlin 复制代码
@JsExport
interface DataProcessor {
    suspend fun process(): String
}

TypeScript 侧直接实现:

typescript 复制代码
class JsonProcessor implements DataProcessor {
    readonly [DataProcessor.Symbol] = true
    async process(): Promise<string> {
        return "processed JSON data"
    }
}

Kotlin 定义契约,各平台用最自然的方式实现。"共享业务逻辑层"这个愿景又近了一步。

其他值得关注的变化

Maven 配置简化kotlin-maven-plugin 加一行 <extensions>true</extensions>,就能自动注册源码目录和 stdlib 依赖,不用再手写 <sourceDirectory> 了。

Vert.x 空安全 :编译器现在能识别 Vert.x 的 @Nullable 注解,自动推断为可空类型。

Java 只读集合@Unmodifiable@UnmodifiableView 标记的集合,在 Kotlin 中会被视为只读类型。目前是警告,2.5.0 将升级为错误。

Map.Entry.copy() :新增实验性 API,可以创建 Map.Entry 的不可变副本。在遍历并修改 Map 时保留 entry 引用,非常实用。

Lombok 插件升级到 Alpha:从实验状态提升,JetBrains 计划做到生产可用。Kotlin/Java 混合项目的好消息。

Gradle 兼容范围:支持 Gradle 7.6.3 到 9.3.0,JVM 编译默认使用 Build Tools API。

如何升级

kotlin 复制代码
plugins {
    kotlin("jvm") version "2.3.20"
}

最新版 IntelliJ IDEA 和 Android Studio 已内置支持。命令行编译器可以从 GitHub Release 页面下载。

写在最后

Kotlin 2.3.20 是一个增量版本,但基于名称的解构声明是一个期待已久的语言级改进。它解决的不是什么"高级"问题,而是每个 Kotlin 开发者都可能踩到的坑。

JPA 插件的简化、Wasm 的性能飞跃、TypeScript 互操作的突破,也反映出 Kotlin 团队在多个方向上的持续发力。

你之前被解构声明的顺序坑过吗?欢迎评论区分享你的经历!

相关推荐
阿拉斯攀登2 小时前
第 16 篇 摄像头驱动适配,V4L2 子系统详解
android·驱动开发·rk3568·瑞芯微·rk安卓驱动
zklgin2 小时前
MySQL错误-this is incompatible with sql_mode=only_full_group_by完美解决方案
android·sql·mysql
牢七2 小时前
baijiacms-master 审计实验
android
刘信的csdn2 小时前
Android Audio模块框架和基础属性概念讲解
android
回到原点的码农2 小时前
MySQL-mysql zip安装包配置教程
android·mysql·adb
mygljx11 小时前
【MySQL 的 ONLY_FULL_GROUP_BY 模式】
android·数据库·mysql
冬奇Lab14 小时前
AudioTrack音频播放流程深度解析
android·音视频开发·源码阅读
青莲84316 小时前
查找算法详解
android·前端
青莲84316 小时前
排序算法详解
android·前端