generics - 在 kotlin 中,测试泛型类型的值是否实现接口(interface),然后将其用作该接口(interface)的正确方法是什么?

标签 generics kotlin

给定一个接受泛型参数的方法,我想检查该类型是否实现了 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 的推荐方法,还是有其他解决方案可以避免未经检查的强制转换?

最佳答案

您的示例中的强制转换显然是必要的,因为您只确保 aComparable未知类型(星形投影)。这个 Actor 阵容甚至可能失败。想一个类A: Comparable<B> .您可以将其转换为 Comparable<A>虽然只能和B比较.

你也可以考虑提供两个函数,一个限制为T: Comparable<T>使用一个上限,一个用于不可比较的类型。在这种情况下,您不需要转换任何东西。

关于generics - 在 kotlin 中,测试泛型类型的值是否实现接口(interface),然后将其用作该接口(interface)的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55333089/

相关文章:

swift - 专门化协议(protocol)继承的通用功能要求

java - 为什么我不能在接收参数化参数的方法中使用通配符?

java - Comparable<T> 与 Raw Comparable

android - 如何在Android中排除jar文件?

java - Android KeyStore 加密和解密数据

java - 将对象转换为通用类型以返回

java - 使用静态方法泛型时不兼容的类型

android - 如何在撰写中围绕多行文本绘制边框

kotlin - IntelliJ 编译器关于为 varargs 传播空数组的警告

spring - Spring Boot运行错误bootRun工作正常,但应用程序运行不正常