【问题标题】:How to deal with generic bounds migrating from Java to Kotlin?如何处理从 Java 迁移到 Kotlin 的泛型边界?
【发布时间】:2017-11-26 05:52:15
【问题描述】:

我的目标是让接口方法接受实现的类类型。这是我到目前为止编写的代码:

internal interface Diff<Diff> {   //in Java I was using <? extends Diff>
    fun lessThan(other: Diff): Boolean
}

private class ADiff(private val value: Int) : Diff<ADiff> {

    override fun lessThan(other: ADiff): Boolean {
        return value < other.value
    }

}

//B can now accept even int types which is not desired
private class BDiff(private val value: Int) : Diff<Int> {

    override fun lessThan(other: Int): Boolean {
        return value < other
    }

}

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

    之所以在 Java 中“有效”是因为 &lt;T extends Diff&gt; 使用了 raw type Diff。不要这样做!


    你能得到的最接近的是使用递归类型绑定:

    interface Diff<T : Diff<T>> {
        fun lessThan(other: T): Boolean
    }
    

    问题是,您可以替换 Diff 的任何其他子类型。

    然而,当使用Diff时,使用泛型类型约束T : Diff&lt;T&gt;

    fun <T : Diff<T>> diffUser(diff1: T, diff2: T) {
        println(diff1.lessThan(diff2))
    }
    

    并且任何未实现Diff&lt;SameType&gt;Diff 将不被接受。

    例子:

    class CDiff(private val value: Int) : Diff<DDiff> { // <-- Wrong type!
        override fun lessThan(other: DDiff) = value < other.value
    }
    
    class DDiff(val value: Int) : Diff<DDiff> {
        override fun lessThan(other: DDiff) = value < other.value
    }
    
    fun test() {
        diffUser(CDiff(3), CDiff(4)) // <-- Doesn't compile due to the generic constraint
        diffUser(DDiff(3), DDiff(4))
    }
    

    This same approachComparable 类使用。


    虽然这可行,但您真正想要的是“自我类型”and this is not supported, although it was on the roadmap at some point。我相信 JetBrains 拒绝了这个请求,尽管我找不到错误报告。

    This answer 详细介绍了在 Java 中使用 the CRT pattern 的解决方法,尽管它不一定是类型安全的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-05
      • 1970-01-01
      相关资源
      最近更新 更多