跳到主要内容

Kotlin 2.5 未使用返回值检查器实战:让编译器帮你揪出那些被静默吞掉的关键结果

· 阅读需 6 分钟
重庆 Kotlin User Group

你有没有遇到过这种场景:代码跑得好好的,测试也通过了,但生产环境就是偶尔出现数据对不上的问题?最后排查了半天,发现罪魁祸首是一个被默默忽略的函数返回值。

来看一段看似无害的代码:

fun processOrder(order: Order) {
val cart = order.cart
// 移除库存不足的商品
cart.items.filter { it.inStock }
// 应用优惠券
cart.total.applyDiscount(order.coupon)
// 保存到数据库
repository.save(cart)
}

问题在哪?filter 不会修改原列表,它返回一个新列表;applyDiscount 如果返回的是新对象而非原地修改,那折扣根本没生效。两行代码的返回值都被静默丢弃了,但编译器一言不发。

Kotlin 2.4.20 when 表达式 invokedynamic 稳定版实战:告别 instanceof 链,拥抱 typeSwitch 字节码

· 阅读需 7 分钟
重庆 Kotlin User Group

你可能不知道,Kotlin 的 when 表达式在 JVM 上编译后,会生成一串冗长的 instanceof 检查。每个分支都是一次类型判断,分支越多,字节码越膨胀。但从 Kotlin 2.4.20 开始,这一切变了——when 表达式正式支持 invokedynamic 编译,默认启用,无需任何额外配置。

来看一个典型的场景:

sealed class Result
data class Success(val data: String) : Result()
data class Error(val message: String, val code: Int) : Result()
object Loading : Result()

fun handleResult(result: Result): String = when (result) {
is Success -> "数据: ${result.data}"
is Error -> "错误 ${result.code}: ${result.message}"
is Loading -> "加载中..."
}

Kotlin 2.4 Map fallback 新 API 实战:用 getOrPutIfNull 和 getOrPutIfMissing 告别手动判空

· 阅读需 6 分钟
重庆 Kotlin User Group

在处理配置、缓存或数据映射时,你一定遇到过这样的场景:从 Map 中获取值,如果不存在就提供默认值。Kotlin 的 getOrDefault() 和 getOrPut() 已经很实用了,但它们都有一个盲区——无法区分"键不存在"和"值为 null"。

来看一个真实的例子:

val config = mutableMapOf<String, String?>(
"username" to "alice",
"theme" to null // 用户明确设置了 theme 为 null
)

// 问题:getOrDefault 无法区分"键不存在"和"值为 null"
val theme1 = config.getOrDefault("theme", "light")
println(theme1) // 输出: light ❌ 错误!用户明确设置了 null,应该保留 null

val theme2 = config.getOrDefault("language", "zh-CN")
println(theme2) // 输出: zh-CN ✅ 正确,键不存在时使用默认值

Kotlin 2.4 集合字面量实战:用方括号语法告别 listOf 和 mutableListOf

· 阅读需 5 分钟
重庆 Kotlin User Group

如果你写过 Kotlin,一定对下面这种代码再熟悉不过了:

val names = listOf("Alice", "Bob", "Charlie")
val scores = mutableListOf(95, 87, 72)
val matrix = listOf(listOf(1, 0), listOf(0, 1))

每次创建集合都要敲一遍 listOf() 或 mutableListOf(),嵌套的时候更是括号套娃。Kotlin 2.4 带来了集合字面量(Collection Literals)——一个期待已久的实验性特性,让你可以直接用方括号 [] 创建集合,就像写 JSON 数组一样自然。

Kotlin 2.4.20 集合新 API 实战:用 allDistinct 和 allEqual 告别手动循环判重

· 阅读需 4 分钟
重庆 Kotlin User Group

在日常开发中,你一定写过这样的逻辑:判断一个列表里的元素是否全部相同,或者检查某个字段是否存在重复。过去我们要么手写 for 循环,要么借助 toSet().size == size 这种"凑合能用"的写法。Kotlin 2.4.20 在标准库中正式引入了 allDistinct()、allEqual() 以及它们的 By 变体,把这些常见需求提升为一等公民 API。

Kotlin 非局部 break/continue 实战:告别标签地狱的循环控制新姿势

· 阅读需 6 分钟
重庆 Kotlin User Group

在 Kotlin 中遍历集合并使用高阶函数时,你一定遇到过这样的困境:想在 lambda 里跳过某次迭代或提前终止循环,却发现 continue 和 break 根本无法直接使用——它们只能作用于字面量循环体,而不是 lambda 内部。于是你不得不搬出标签(label),写出 loop@、return@loop、continue@loop 这样令人眼花缭乱的代码。Kotlin 2.2 将非局部 break 与 continue 正式转为稳定特性,让这类跳转变得自然直观。

Kotlin 2.5 标准库新成员:onTrue、onFalse、ifOrNull 实战指南

· 阅读需 5 分钟
重庆 Kotlin User Group

在日常 Kotlin 开发中,你一定写过这样的代码:调用一个返回 Boolean 的方法,然后根据结果做点副作用——记个日志、发个通知、返回个值。这类模式看似简单,写多了却会让代码变得冗长而重复。Kotlin 2.5.0-Beta1 带来了三个小巧但实用的标准库函数,专门解决这类问题。

Kotlin 标准库 UUID 实战:从 java.util.UUID 到 kotlin.uuid.Uuid 的跨平台迁移指南

· 阅读需 6 分钟
重庆 Kotlin User Group

在几乎所有像样的项目中,你都会遇到 UUID——数据库主键、会话标识、设备指纹、分布式追踪 ID,处处都有它的身影。长期以来,Kotlin 开发者在 JVM 上直接用 java.util.UUID,在 iOS 上用 NSUUID,在 JS 上用 crypto.randomUUID()。三种类型、三套 API、三种序列化方式——跨平台项目中还得写适配层来互相转换。

Kotlin 2.4 终于结束了这个局面:kotlin.uuid.Uuid 正式从实验性 API 毕业,成为标准库的稳定成员。

Kotlin 标准库安全支持策略实战:18 个月支持窗口的工程化落地指南

· 阅读需 7 分钟
重庆 Kotlin User Group

在企业级项目中,依赖库的安全合规往往比功能本身更受关注。合规团队需要知道每个依赖的安全支持截止日期,安全审计需要确认漏洞修复是否在受支持的版本窗口内,采购流程需要供应商提供正式的文档化支持信号。长期以来,Kotlin 在这方面缺乏一份明确的安全支持策略——直到 Kotlin 2.4 的发布。

Kotlin 多美元符号插值实战:告别 ${'$'} 转义地狱的优雅方案

· 阅读需 6 分钟
重庆 Kotlin User Group

你是否在 Kotlin 中写过包含大量 $ 符号的字符串?JSON Schema、正则表达式、Shell 脚本模板、SQL 语句……这些场景里的美元符号无处不在,而 Kotlin 的字符串插值恰好也以 $ 作为触发符。于是,一个令人头疼的问题出现了:你不得不用 ${'$'} 逐个转义每个字面量美元符号,代码变得支离破碎。Kotlin 2.1.0 引入的 多美元符号字符串插值(Multi-Dollar String Interpolation) 特性,正是为了解决这个痛点。