Home > Enterprise >  Kotlin infix function with generics
Kotlin infix function with generics

Time:05-29

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

CodePudding user response:

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))

CodePudding user response:

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.

CodePudding user response:

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()
    }
}
  • Related