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

为何Kotlin的sumOf函数Lambda内默认不将数字视为Int类型?

Kotlin sumOf重载歧义问题解析

问题重现

执行以下代码时,Kotlin编译器会抛出重载解析歧义错误:

val sum = listOf(1, 2, 3).sumOf { if (it % 2 == 0) 1 else 0 }

错误信息如下:

Kotlin: Overload resolution ambiguity:
public inline fun Iterable<TypeVariable(T)>.sumOf(selector: (TypeVariable(T)) -> Int): Int defined in kotlin.collections
public inline fun Iterable<TypeVariable(T)>.sumOf(selector: (TypeVariable(T)) -> Long): Long defined in kotlin.collections

如果显式调用toInt(),错误会消失,但会出现冗余调用警告:

val sum = listOf(1, 2, 3).sumOf { if (it % 2 == 0) 1.toInt() else 0 }

原因分析

Kotlin的数字字面量(如1、0)属于无类型字面量,编译器会根据上下文自动推断其类型。而sumOf函数提供了两个重载:

  • 一个接受返回Int类型的选择器函数,返回Int结果
  • 另一个接受返回Long类型的选择器函数,返回Long结果

由于Kotlin支持Int到Long的隐式拓宽转换,1和0既可以被推断为Int,也可以被推断为Long。此时编译器没有足够的上下文信息确定你要调用哪个重载版本,因此抛出歧义错误。

显式调用1.toInt()时,相当于强制指定了选择器函数的返回类型为Int,编译器就能明确匹配到对应重载。但因为字面量1本身可以直接被当作Int,所以toInt()调用是冗余的,会触发警告。

更优雅的解决方案

不需要使用冗余的toInt(),可以通过以下方式消除歧义:

  • 方式1:给目标变量指定类型,让编译器反向推断选择器的返回类型:
val sum: Int = listOf(1, 2, 3).sumOf { if (it % 2 == 0) 1 else 0 }
  • 方式2:显式指定lambda的返回类型:
val sum = listOf(1, 2, 3).sumOf { (if (it % 2 == 0) 1 else 0) as Int }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 12:06:43