带有泛型的 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 是 Float)可以这样处理:
is Float -> this + that.toLong()
导致 1230000000000000123
或者可以这样处理:
is Float -> this.toFloat() + that
导致 1.23E18
尝试写一个简单的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 是 Float)可以这样处理:
is Float -> this + that.toLong()
导致 1230000000000000123
或者可以这样处理:
is Float -> this.toFloat() + that
导致 1.23E18