首页 > 解决方案 > kotlin 泛型和运算符重载

问题描述

我想做这样的事情

data class TestGen<T: Number>(var x : T, var y : T)

public operator<T:Number> fun Int.plus(p:TestGen<T>) = TestGen(this+p.x,p.y)

那我该怎么做呢?或任何其他想法做同样的事情?因为我想做这样的事情

public operator fun Int.plus(p:TestGen<Float>) = TestGen(this+p.x,p.y)
public operator fun Int.plus(p:TestGen<Double>) = TestGen(this+p.x,p.y)

标签: genericskotlinoperator-overloading

解决方案


首先,您的扩展函数声明中有语法错误。其次,aNumber不会自动定义加+另一个数字的能力。Number因此,使用泛型基类型会产生问题。不幸的是,您需要创建您希望对所有数字类型有效的所有排列。

打破它...

operator <T: Number> fun Int.plus(p:TestGen<T>) = TestGen(this+p.x,p.y)

是无效的语法。以下更正确,但由于“类上不存在加法”的原因仍然无法编译Number

operator fun <T: Number> Int.plus(p:TestGen<T>) = TestGen(this+p.x,p.y)

因此,要修复它,您真正需要的是删除函数的通用参数,并具体说明您支持的每种类型:

@JvmName("IntPlusTestGenWithInt")
operator  fun Int.plus(p:TestGen<Int>) = TestGen(this+p.x,p.y)
@JvmName("IntPlusTestGenWithLong")
operator  fun Int.plus(p:TestGen<Long>) = TestGen(this+p.x,p.y)
@JvmName("IntPlusTestGenWithDouble")
operator  fun Int.plus(p:TestGen<Double>) = TestGen(this+p.x,p.y)
@JvmName("IntPlusTestGenWithFloat")
operator  fun Int.plus(p:TestGen<Float>) = TestGen(this+p.x,p.y)
// etc

注释是必需的JvmName,因为您正在创建仅因通用参数不同而被 JVM 擦除的扩展方法。因此,在内部,Kotlin 生成的字节码必须按名称区分每个扩展方法,即使您不会从 Kotlin 代码中看到这一点。

对于要从​​中添加的所有类型,您将需要类似的函数变体。并且您应该考虑您正在对不再有意义的部分数字做什么,例如,Double添加到a 的小数部分Int


推荐阅读