You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中chunked与async、await搭配使用出现异常行为如何解决?

异常行为根因
  • Kotlin 标准库的 Iterable<T>.chunked(size: Int, transform: (List<T>) -> R) 重载为了优化性能,transform 入参接收的分片列表是复用的可变实例:每处理完一个分片,标准库会直接清空该列表对象,填充下一分片的元素,不会为每个分片单独创建新的列表实例。
  • 你在 transform 中直接启动 async 异步任务时,async 的代码块不会立即执行,需要等待协程调度。等到两个 async 代码块实际执行并调用 it.first() 时,分片列表已经被迭代到第二个分片,内容已经更新为 ["world"],因此两次 translate 调用传入的都是 world,最终输出 mundomundo。
修复方案

可以选择以下任意一种方式修复:

  1. 启动异步任务前先捕获当前分片的快照:在 transform 内先把需要的内容拷贝到局部变量,再传入 async 块
val chunks = hello.chunked(1) { chunk ->
    // 提前拷贝当前分片的内容,脱离复用的可变列表实例
    val currentWord = chunk.first()
    async { translate(currentWord) }
}
  1. 使用不带 transform 参数的 chunked 重载:该重载返回的是存储了独立不可变分片的列表,不存在实例复用问题
val chunks = hello.chunked(1)
    .map { chunk ->
        async { translate(chunk.first()) }
    }
需要注意的特性要点
  • 标准库中 chunked、windowed 这类批量处理的变换函数,只要使用带 transform 参数的重载,传入的集合都是复用的可变实例,仅在 transform 函数执行的当前栈帧内有效,不能异步持有其引用。
  • 协程的 async、launch 等构建器的代码块是延迟执行的,闭包捕获外部变量时要注意变量的可变性和生命周期,避免后续变量被修改后得到不符合预期的结果。

内容的提问来源于stack exchange,提问作者Elfogre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 05:57:03