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

Kotlin中如何使用泛型实现不同类型数值的相加

错误原因梳理
  • 泛型无界导致编译不通过:定义的<T, U>没有指定类型上界,T可以是任意类型,编译器无法确认T拥有可接收U类型参数的plus方法,直接调用a.plus(b)会触发编译错误。
  • 自定义泛型plus扩展完全无效:编写的operator fun <U> U.plus(b: U) {}存在核心缺陷:一是给所有类凭空添加了一个无实际计算逻辑、返回Unit的plus方法,既会污染所有类型的plus行为,还会和原生数值的plus运算符产生冲突;二是该扩展要求接收者类型和参数类型完全一致,传入Int类型接收者、搭配Double类型参数的调用根本无法匹配这个扩展。
  • 对原生plus声明的误解:看到的无函数体的plus定义,是Kotlin标准库为内置数值类型定义的编译期内置运算符——这些函数没有普通的JVM方法实现,编译时会直接被翻译为对应基本类型的加法字节码,不存在通用的、可适配所有泛型数值类型的plus接口。
正确实现思路

Kotlin的所有内置数值类型(Byte/Short/Int/Long/Float/Double)都实现了Number抽象类,我们可以通过给泛型加上Number上界,限定参数必须是数值类型,再根据精度需求选择合适的策略完成加法。

通用简洁实现(统一转Double兼容所有数值类型)

直接将两个数值参数统一转换为精度最高的Double类型完成计算,代码简洁,不存在类型匹配问题:

fun <T: Number, U: Number> add(a: T, b: U): Number {
    return a.toDouble() + b.toDouble()
}

fun main() {
    println(add(4, 5.6)) // 输出9.6
    println(add(2L, 3)) // 输出5.0
    println(add(1.toByte(), 2.5f)) // 输出3.5
}

智能精度适配实现(匹配最优返回类型)

如果不希望整数之间的加法返回带小数点的Double类型,可以通过类型判断,按精度优先的原则选择最合适的数值类型做计算:

fun <T: Number, U: Number> addSmart(a: T, b: U): Number {
    return when {
        // 任意参数是Long则统一转Long计算,避免整数溢出
        a is Long || b is Long -> a.toLong() + b.toLong()
        // 任意参数是Int则转Int计算
        a is Int || b is Int -> a.toInt() + b.toInt()
        // 只要存在浮点类型则统一转Double计算保证精度
        else -> a.toDouble() + b.toDouble()
    }
}

fun main() {
    println(addSmart(4, 5.6)) // 输出9.6 (Double)
    println(addSmart(100, 200)) // 输出300 (Int)
    println(addSmart(1000, 2000L)) // 输出3000 (Long)
}

注:由于Kotlin的Number抽象类本身没有定义跨类型的加法接口,无法在不做类型判断的前提下实现完全静态的、和原生运算符精度完全一致的泛型加法,上述两种方案已经覆盖了绝大多数跨数值类型加法的使用场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 17:24:02