```import kotlin.jvm.internal.Reflection inline f...
# announcements
f
Copy code
import kotlin.jvm.internal.Reflection

inline fun <reified T: Number>round(number: T): Int {
    return when(T::class){
        Int::class -> number as Int
        Double::class -> (number as Double).toInt()
        else -> throw IllegalArgumentException("Invalid type")
    }
}

fun test(){
    print(round(1))
    print(round(2.0))
    print(round(3f))
}

fun howShouldBeCompiled(){
    print(1)
    print((2.0 as Number).toInt())
    throw IllegalArgumentException("Invalid type")
}

fun howItIsCompiled() {
    val number = 1
    val type = Reflection.getOrCreateKotlinClass(Int::class.java)
    var result1: Int = when(type){
        Int::class.java -> number
        Double::class.java -> (number as Double).toInt()
        else -> throw java.lang.IllegalArgumentException("Invalid type")
    }
    print(result1)
    
    //... do the same for each case
}
Is there a way to inline reified generic functions at compile time? Isn't T::class known at compile time? The only alternative which I see is removing the generic and manually overload each possible accepted class (in this case it's just two, but I have more complex cases with like 8 input classes). I feel like having only one function declaration with a switch (when) is more elegant than 8 declarations with overload (for simple functions).
y
Well first of all the reflection comparisons there should be optimised by the JVM at run-time and so it won't actually take that much of a performance hit since it is a constant condition (as in every single time
howItIsCompiled
is called it always does the same exact boolean equality checks and so the JVM will optimise that away. However if you do want to 100% get rid of that reflection, then what you can do is either this:
Copy code
inline fun <reified T: Number>round(number: T): Int { //There's no need for this to be reified in this case but I kept the reified modifier because why not
    return when(number){
        is Int -> number
        is Double -> number.toInt()
        else -> throw IllegalArgumentException("Invalid type")
    }
}
or this:
Copy code
inline fun <reified T: Number>round(number: T): Int {
    // Using constants that are guaranteed to only be one specific Number type
    return when {
        0 is T -> number as Int
        0.0 is T -> (number as Double).toInt()
        else -> throw IllegalArgumentException("Invalid type")
    }
}
This effectively just makes this a couple instance checks which the JVM is probably better at inlining