如何避免Kotlin Generic的类型不匹配错误?

时间:2019-03-05 06:44:21

标签: generics kotlin

代码段

fun main() {
    val myClass : AbsClass<Any> = MyClass()
    // Error - type mismatch

    val myClass : AbsClass<*> = MyClass() 
    // Not Error, but parameter of 'foo' is 'Nothing'

    val myClass : AbsClass<Any> = MyClass() as AbsClass<Any> 
    // It's correct works with unchecked cast warning and unnecessary casting code.

    myClass.foo(MyModel())
}

class MyClass() : AbsClass<MyModel>() {
}

abstract class AbsClass<T> {
    fun foo(value:T){}
}

data class MyModel(val number:Int = 0)

问题

我想将代码编写为val myClass : AbsClass<Any> = MyClass(),但是它显示类型不匹配错误。如何解决此问题(避免使用类型转换代码as AbsClass<Any>)?

1 个答案:

答案 0 :(得分:3)

您应该使用:

val myClass: AbsClass<out Any> = MyClass()` or `val myClass: AbsClass<in Nothing> = MyClass()

out关键字意味着您希望将任何子类型分配给超类型。 MyModel可以分配给Any,所以可以。

in关键字意味着您希望可以将任何超类型分配给子类型(在本例中为Nothing),因此可以使用MyModel,因为它是Nothing的超类型。 / p>

我认为,这样一来,如果不提供任何预期类型的​​信息(您可以指定类似AbsClass<T : MyAbstractModel>的信息),那么在不进行强制转换或反射的情况下,几乎没有任何可能性。

这是类型差异,它是OOP中最困难的想法之一。您可以在这里阅读更多内容:  https://kotlinlang.org/docs/reference/generics.html#variance