Kotlin 中具体泛型的重载解析

问题描述

我想根据具体化的类型参数返回不同的类型。我尝试使用重载,但重载解析似乎不正确。

我的目标是在运行时存储一组接近的类型,如下所示:

sealed interface Type<T> {
  object Int: Type<kotlin.Int>
  object Boolean: Type<kotlin.Boolean>
}

inline fun<reified T> get() : Type<T> = getImpl(null as T?)

fun getImpl(a: Int?) : Type<Int> = Type.Int
fun getImpl(a: Boolean?) : Type<Boolean> = Type.Boolean
fun <T>getImpl(a: T?) : Type<T> = error("Unsupported type")

fun main() {
    println(getImpl(null as Int?)) // return Type.Int as expected
    println(get<Int>()) // Same as above after get is inlined but throws!
}

会不会是在方法被内联之前就解决了重载?

目标是让一些泛型类采用 Type<T> 参数并保证 T 在闭集中。它还允许在运行时测试泛型类型 T解决方法类型擦除)。

我宁愿避免让客户端明确指定 Type.Int 或使用未经检查的强制转换来实现,例如:

inline fun<reified T> getUncheckedCast() : Type<T> =
  when (T::class) {
    Int::class -> Type.IntType as Type<T>
    Boolean::class -> Type.BooleanType as Type<T>
    else -> error("Unsupported type")
  }

解决方法

我认为你的最后一个代码块是最好的解决方案。尽管您的 get 函数被具体化,但该类型仍然是泛型的,因此编译器会将重载解析为引发错误的泛型。您无法让编译器选择在运行时调用哪个重载。它总是在编译时被选中。

,

根据 Kotlin documentationreified 参数的唯一区别在于其运行时类可用:

4.5.2 具体化的类型参数加载测试

内联函数声明的类型参数(并且只有那些)可以使用相应的关键字进行具体化。 reified 类型参数是函数作用域内的 runtime-available 类型,详见相应章节。

它没有指定在函数内联时替换类型。 这意味着 reified 正在为隐式传递具体化类型的 KClass 加糖:

inline fun <reified T>f() = T.class
// is desugared to
inline fun <T>f(__TKClass : KClass<T>) = __TKClass

因此重载解析集不受具体化类型的影响。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...