5

将函数添加到基于类型的类的惯用方法是什么。下面的例子使用 List 作为类,Type Parameter<T>是列表内对象的类。假设您想根据它们的类型使用不同的比较器对这些列表中的每一个进行排序。

data class A(val foo: String)
data class B(val bar: Int)

private val aComparator: Comparator<A> = Comparator { lhs, rhs -> rhs.foo.compareTo(lhs.foo) }
private val bComparator: Comparator<B> = Comparator { lhs, rhs -> rhs.bar.compareTo(lhs.bar) }

fun <T: A> List<T>.sort(): List<T> {
    return this.sortedWith<T>(aComparator)
}

fun <T: B> List<T>.sort(): List<T> {
    return this.sortedWith<T>(bComparator)
}

这给出了一个错误,指出由于 Java 的重载规则,两个排序函数具有相同的签名。在 Java 中,我可能会给它们两个不同的可识别名称,但它作为 Kotlin 扩展(egasortA() b.sortB())相当难看。Kotlin 不会将 sortA 显示到 List< B > 所以似乎会有更好的方法来编写 sort() 来处理不同对象上的不同比较器。

该示例非常简单,但想象一下,如果我无权修改 A 类和 B 类,因此我无法使用继承或在它们上实现接口。我还考虑为每个类添加一个比较器并使用 Any? 但这似乎也很麻烦。

4

2 回答 2

14

一个答案似乎是:

@JvmName("sortA")
fun <T: A> List<T>.sort(): List<T> {
    return this.sortedWith<T>(aComparator)
}

@JvmName("sortB")
fun <T: B> List<T>.sort(): List<T> {
    return this.sortedWith<T>(bComparator)
}

这似乎解决了 Java 的泛型类型擦除问题。

在这里找到:https ://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

于 2016-01-09T03:50:09.887 回答
0

在这个网站上,我找到了这个解决方案

而不是这个

fun Iterable<Long>.average(): Double {}
fun Iterable<Int>.average(): Double {}

使用平台名称

fun Iterable<Long>.average(): Long {
}
platformName("averageOfInt") fun Iterable<Int>.average(): Int {
}

编辑:这已被弃用,请改用 JvmName。

于 2016-01-09T04:07:51.327 回答