给定一个接受泛型参数的方法,我想检查该类型是否实现了 Comparable,如果是,则将其与另一个值进行比较。
假设类型参数为 T,由于 T 被删除,所以形式为 t is Comparable<T>
的测试是不可能的,即使有具体的类型参数。 t is Comparable<*>
形式的测试是可能的并且有效,但是 t 不能用作 Comparable,因为 Comparable<*> 是超出投影的。
fun <T> examine(a: T, b: T) {
if (a is Comparable<*>) {
a <= b
}
}
这失败了:
Kotlin: Out-projected type 'Comparable<*>' prohibits the use of 'public abstract operator fun compareTo(other: T): Int defined in kotlin.Comparable'
我可以看到的一种解决方法是
fun <T> examine(a: T, b: T) {
if (a is Comparable<*>) {
println(a as Comparable<T> <= b)
}
}
哪个有未经检查的类型转换,但为什么这个类型转换是必要的?
智能类型转换是否应该因为我们为检查 a 是否具有可比性而进行的测试而忽略这一点?不同的类型参数是否不允许智能转换在这里发生?
这是测试 Comparable 的推荐方法,还是有其他解决方案可以避免未经检查的强制转换?
最佳答案
您的示例中的强制转换显然是必要的,因为您只确保 a
是 Comparable
未知类型(星形投影)。这个 Actor 阵容甚至可能失败。想一个类A: Comparable<B>
.您可以将其转换为 Comparable<A>
虽然只能和B
比较.
你也可以考虑提供两个函数,一个限制为T: Comparable<T>
使用一个上限,一个用于不可比较的类型。在这种情况下,您不需要转换任何东西。
关于generics - 在 kotlin 中,测试泛型类型的值是否实现接口(interface),然后将其用作该接口(interface)的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55333089/