Kotlin 中改进的内联函数仍然导致 'is' 检查时出现编译器错误

Reified inline function in Kotlin still leading to compiler error on 'is' check

我有以下功能:

inline fun <reified T> create(preference: Preference<T>, title: String = ""): DebugOption{
        val type = when (preference) {
            is Preference<String> -> Type.STRING
            is Preference<Boolean> -> Type.BOOLEAN
            else -> Type.STRING
        }

        return DebugOption(type, preference, displayTitle = StringModel(title))
    }

我希望能够轻松地执行此 'is' 检查,因为通用类型已具体化,但我仍然遇到编译器错误:

Cannot check for instance of erased type: Preference<String>
Cannot check for instance of erased type: Preference<Boolean>

所以我很困惑我是如何滥用 'reified' / 我在这里错过了什么。 使用具体化的泛型类型作为另一个 class 的类型参数有问题吗?

问题是 is 检查 preference 运行时类型 ,而 preference 的运行时类型直到所有通用类型信息都已被删除。

您可以改为检查 T,因为如您所说,T 确实已具体化。

val type = when (T::class) {
    String::class -> Type.STRING
    Boolean::class -> Type.BOOLEAN
    else -> Type.STRING
}

但请注意,如果 Preference 是协变的(如 List)或逆变的,这在某些情况下可能无法像您预期的那样工作。例如:

// suppose Preference is covariant 
// (i.e. the type parameter is declared <out T>)
val pref: Preference<Any> = Preference<Boolean>()
create(pref, "foo")

在这种情况下,T被推断为Any,因此type将被赋值为Type.STRING。如果这对您来说出乎意料,并且您想要 Type.BOOLEAN,您可能希望使用另一种方法来检查首选项的类型,而不是具体化的类型,因为这无法在编译时确定。