Try to write a simple Kotlin infix function for plus operation. What's wrong with generic type?
infix fun <T : Number> T.myPlus(that: T): T = this + that
Try to write a simple Kotlin infix function for plus operation. What's wrong with generic type?
infix fun <T : Number> T.myPlus(that: T): T = this + that
As others have mentioned, there's no solutions using generics for various reasons. You have to define an extension function for each Number type (Byte, Short, Int, Long, Float, Double). E.g. for Int you could do:
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")
}
Even doing that, in some cases you need to decide whether you want to truncate or round the result.
val n1 = 1230000000000000000L
val n2 = 123.7
This case (n1 is a Long, n2 is a Float) could be handled like this:
is Float -> this + that.toLong()
resulting in 1230000000000000123
or it could be handled like this:
is Float -> this.toFloat() + that
resulting in 1.23E18
You forgot the operator keyword:
infix operator fun T.plus(that: T): T = this + that
Edit:
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))
A bit more casting safety:
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")
}
}
In prev. example args:
val n1 = 1230000000000000000L
val n2 = 123
val result = n1 infixPlus n2
result: -1313144709
No exception and wrong result.
You have to find the correct type of the result:
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()
}
}