franztesca
03/21/2021, 11:35 AMimport 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).Youssef Shoaib [MOD]
03/21/2021, 12:22 PMhowItIsCompiled
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:
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:
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