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
,您可能希望使用另一种方法来检查首选项的类型,而不是具体化的类型,因为这无法在编译时确定。
我有以下功能:
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
,您可能希望使用另一种方法来检查首选项的类型,而不是具体化的类型,因为这无法在编译时确定。