首页 > 解决方案 > 为什么我必须输入这个 Kotlin 代码?

问题描述

interface Foo<T: Bar> {
    fun example(bar: T)
}

interface Bar

class Bar1 : Bar

class Bar2 : Bar

class FooEx1 : Foo<Bar1> {
    override fun example(bar: Bar1) { }
}

class FooEx2 : Foo<Bar2> {
    override fun example(bar: Bar2) { }
}

// Won't compile
// Even though FooEx1 and FooEx2 *are* Foo<Bar>
class ExampleDoesntCompile {
    val collection = mutableListOf<Foo<Bar>>().apply {
        this.add(FooEx1())
        this.add(FooEx2())
    }
}

// Will compile
// But have to cast FooEx1 and FooEx2 to Foo<Bar>
class ExampleDoesCompileButRequiresCast {
    val collection = mutableListOf<Foo<Bar>>().apply {
        this.add(FooEx1() as Foo<Bar>)
        this.add(FooEx2() as Foo<Bar>)
    }
}

因此,例如,我可以声明 Foo 的参数化类型为out,但随后我得到函数的编译错误example

interface Foo<out T: Bar> {
    fun example(bar: T)
}

错误:Type parameter T is declared as 'out' but occurs in 'in' position in type T

标签: kotlingenerics

解决方案


因为 Java / Kotlin 中的泛型类型默认是不变的。方差

interface Foo<out T: Bar>

如果您不能使其成为协变的,则使列表项成为协变的

val collection = mutableListOf<Foo<out Bar>>().apply {
    this.add(FooEx1())
    this.add(FooEx2())
}

 //or  val collection = mutableListOf(FooEx1(), FooEx2())

推荐阅读