Kotlin 中具体化泛型的重载解析

Overload resolution of reified generic in Kotlin

我想 return 不同的类型取决于具体化的类型参数。我尝试使用重载,但重载解析似乎不正确。

我的目标是像这样在运行时存储一组接近的类型:

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 函数已具体化,但该类型仍然是通用的,因此编译器会将重载解析为引发错误的通用类型。您无法让编译器 select 在运行时调用哪个重载。它总是在编译时 selected。

根据 Kotlin documentation,参数 reified 的唯一区别是其运行时 class 可用:

4.5.2 Reified type parametersLoad tests

Type parameters of inline function declarations (and only those) can be declared reified using the corresponding keyword. A reified type parameter is a runtime-available type inside the function scope, see the corresponding section for details.

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

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

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