Kotlin 中泛型的子类型问题

Subtype issues with generics in Kotlin

我的代码中有以下继承模式。

trait  A {
    fun foo(): Set<A>
}

trait B : A {
    override fun foo(): MutableSet<B>
}

trait C : A {
    override fun foo(): Set<C>

}

trait D : C, B {
    override fun foo(): MutableSet<D>
}

当 B 和 D return 设置时,编译器能够确定 Set<D>Set<B>Set<C> 的子类型。但是,当我将 B.fooD.foo 的 return 类型更改为 MutableSet 时,编译器能够验证 B.foo 的 return 类型但我收到一条错误报告,指出 D.foo 的 return 类型不是 MutableSet<B>.

的子类型

为什么 Kotlin 无法推断出这种形式的子类型,是否有任何解决方法而不需要彻底改变我的层次结构?

覆盖函数的 return 类型 必须 是被覆盖函数的子类型。在您的示例中,MutableSet<D> 不是 MutableSet<B> 的子类型。如果是,类似的代码可能会在运行时导致异常:

trait B {
    fun foo(): MutableSet<B>
}

trait D : B {
    override fun foo(): MutableSet<D>

    fun onlyInD() {}
}

class BImpl : B {
    override fun foo() = null!!
}

class DImpl : D {
    private val set = java.util.HashSet<D>()

    override fun foo() = set
}    

fun main(args: Array<String>) {
    val impl = DImpl()
    // two variables pointing to the same instance
    val b: B = impl 
    val d: D = impl

    b.foo().add(BImpl())

    // ClassCastException on the next line: BImpl is not an instance of D
    d.foo().first().onlyInD()
}

查看 try.kotl.in

上的实例