首页 文章

Kotlin扩展功能按类型

提问于
浏览
4

基于类型向类添加函数的惯用方法是什么?以下示例使用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扩展(例如a.sortA()b.sortB())相当丑陋 . Kotlin没有向List <B>显示sortA,因此似乎有更好的方法来编写sort()来处理不同对象上的不同比较器 .

这个例子非常简单,但想象一下,如果我没有修改类A和B的权限,那么我就无法使用继承或在它们上实现接口 . 我还想过为每个类添加一个比较器并使用Any?但这似乎也很麻烦 .

2 回答

  • 10

    一个答案似乎是:

    @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

  • 0

    On this site, I found this solution

    而不是这个

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

    使用platformName

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

    编辑:这是不推荐使用的,而是使用JvmName .

相关问题