Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按类型划分的Kotlin扩展函数_Kotlin_Kotlin Extension - Fatal编程技术网

按类型划分的Kotlin扩展函数

按类型划分的Kotlin扩展函数,kotlin,kotlin-extension,Kotlin,Kotlin Extension,根据类型向类中添加函数的惯用方法是什么。下面的示例使用List作为类,类型参数是列表中的对象类。假设您希望根据这些列表的类型使用不同的比较器对它们进行排序 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 va

根据类型向类中添加函数的惯用方法是什么。下面的示例使用List作为类,类型参数
是列表中的对象类。假设您希望根据这些列表的类型使用不同的比较器对它们进行排序

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)
}
数据类A(val-foo:String)
B类数据(val bar:Int)
private val aComparator:Comparator=Comparator{lhs,rhs->rhs.foo.compareTo(lhs.foo)}
private val bComparator:Comparator=Comparator{lhs,rhs->rhs.bar.compareTo(lhs.bar)}
乐趣列表。排序():列表{
返回此。与(比较者)一起排序
}
乐趣列表。排序():列表{
返回此.sortedWith(b比较程序)
}
这会导致一个错误,即由于Java的重载规则,两个排序函数具有相同的签名。在Java中,我可能会给它们两个不同的可识别名称,但它与Kotlin扩展(例如a.sortA()b.sortB())一样难看。Kotlin没有向列表显示sortA,因此似乎有更好的方法编写sort()来处理不同对象上的不同比较器


这个例子很简单,但是想象一下,如果我没有权限修改类A和B,那么我就不能使用继承或在它们上实现接口。我还考虑在每个类中添加一个比较器,并使用任何?但这似乎也很麻烦。

一个答案似乎是:

@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)
}
@JvmName(“sortA”)
乐趣列表。排序():列表{
返回此。与(比较者)一起排序
}
@JVM名称(“sortB”)
乐趣列表。排序():列表{
返回此.sortedWith(b比较程序)
}
这似乎通过泛型类型擦除解决了Java的问题

在此处找到:

而不是这个

fun Iterable<Long>.average(): Double {}
fun Iterable<Int>.average(): Double {}
fun Iterable.average():Double{}
fun Iterable.average():Double{}
使用平台名

fun Iterable<Long>.average(): Long {
}
platformName("averageOfInt") fun Iterable<Int>.average(): Int {
}
fun Iterable.average():长{
}
platformName(“averageOfInt”)有趣易用。average():Int{
}

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

此示例使用过时的Kotlin语法,该语法与当前版本不再兼容。上面Jeremy的回答显示了使用最新语法的相同解决方案。
platformName
已被弃用(或现在已被删除),
JvmName
是当前版本。更新到Kotlin 1.0 betas,并观察编译器警告/错误。这并不完全是“泛型类型擦除”。Kotlin可以在编译时区分这两个函数,因为它的签名包括泛型,还可以根据返回类型进行区分。Java不使用泛型类型创建方法签名。因此,这将更改字节码中的实际方法名,重命名它,这样现在就有两个独立的方法,不再需要通过签名进行区分。而不是一个类上的两个重载函数具有明显相同的签名。