【问题标题】:kotlin generics and operator overloadingkotlin 泛型和运算符重载
【发布时间】:2023-03-24 23:45:01
【问题描述】:

我想做这样的事情

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)

【问题讨论】:

    标签: generics kotlin operator-overloading


    【解决方案1】:

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

    打破它...

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

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

    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 的小数部分添加到Int

    【讨论】:

    • @MrAhmed 如果它工作正常,请接受答案以向可能阅读此内容的其他人表明这一事实。
    猜你喜欢
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 2016-01-25
    • 2012-12-10
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多