带有泛型的 Kotlin 中缀函数

Kotlin infix function with generics

尝试写一个简单的Kotlin中缀函数进行加号操作。泛型有什么问题?

infix fun <T : Number> T.myPlus(that: T): T = this + that

您忘记了 运算符 关键字:

中缀运算符有趣 T.plus(that: T): T = this + that

编辑:

infix fun Number.infixPlus(that: Number): Number =
  when (that) {
    is Int    -> this.toInt() + that
    is Long   -> this.toLong() + that
    is Float  -> this.toFloat() + that
    is Double -> this.toDouble() + that
    else      -> throw Exception()
  }

val n1 = 123
val n2 = 123.456

val result = n1 infixPlus n2

println("result: " + result)

println("is Int: " + (result is Int))
println("is Long: " + (result is Long))
println("is Float: " + (result is Float))
println("is Double: " + (result is Double))

铸造安全性更高:

infix fun Number.infixPlus(that: Number): Number {
    return when {
        this is Int && that is Int -> this + that
        this is Double && that is Double -> this + that
        this is Float && that is Float -> this + that
        else -> throw Exception("Types mismatch")
    }
}

上一篇示例参数:

val n1 = 1230000000000000000L
val n2 = 123

val result = n1 infixPlus n2
result: -1313144709

没有异常和错误的结果。

您必须找到正确的结果类型:

val types = listOf("Double", "Float", "Long", "Integer", "Short", "Byte")
infix fun <T : Number> T.myPlus(that: T): T {
    return when(types[min(types.indexOf(this.javaClass.simpleName), types.indexOf(that.javaClass.simpleName))]) {
        types[0] -> (this.toDouble() + that.toDouble()) as T
        types[1] -> (this.toFloat() + that.toFloat()) as T
        types[2] -> (this.toLong() + that.toLong()) as T
        types[3] -> (this.toInt() + that.toInt()) as T
        types[4] -> (this.toShort() + that.toShort()) as T
        types[5] -> (this.toByte() + that.toByte()) as T
        else -> throw IllegalArgumentException()
    }
}

正如其他人所提到的,由于各种原因,没有使用泛型的解决方案。您必须为每种数字类型(Byte、Short、Int、Long、Float、Double)定义一个扩展函数。例如。对于 Int 你可以这样做:

when (that) {
    is Byte, is Short, is Int, is Long -> that.toLong().plus(this)
    is Float -> that + this
    is Double -> that + this
    else -> throw Exception("Types mismatch")
}

即使这样做,在某些情况下您也需要决定是要截断还是舍入结果。

val n1 = 1230000000000000000L
val n2 = 123.7

这种情况(n1 是 Long,n2 是 Fl​​oat)可以这样处理:

is Float -> this + that.toLong()

导致 1230000000000000123

或者可以这样处理:

is Float -> this.toFloat() + that

导致 1.23E18