在 Kotlin 中使用星型投影作为超类型

hon*_*hia 5 generics android kotlin

谁能帮我解释一下这里发生了什么?

private val map1 = mutableMapOf<String, Data<State<*>>>()
private val map2 = mutableMapOf<String, Data<*>>()

init {
    map1.put("1", Data<State<String>>()) //it does not work
    map2.put("2", Data<State<String>>()) //it works
    map2.put("3", Data<State<Int>>()) //it works
}

class Data<T>
class State<T>
Run Code Online (Sandbox Code Playgroud)

我从 Kotlin 文档中读到,如果类型未知,您可以使用星形投影(*),然后再使用任何类型。那么为什么它不适用于第一种情况呢?它说Type Mismatch Error

Ale*_*nov 6

Data<*>Data<String>是, Data<Any>,的共同超类型Data<AnythingYouPutThere>。但Data<State<*>>不是的常见超类型Data<State<String>>;它Data具有特定的类型参数State<*>(这是等的超类型State<String>

不幸的是,Kotlin 不像 Scala 那样支持一般的存在类型,但用这些术语来说Data<State<*>>就是Data<State<T> forSome T>while you need Data<State<T>> forSome T

我设置mutableMapOf<String, Data<State<*>>>()mutableMapOf<String, Data<out State<*>>>()并且成功了。我不知道为什么

Data<out State<*>>允许 的任何子类型State<*>作为 的类型参数Data。因此,它也可以表示为存在类型:Data<T> forSome T : State<*>,但不完全 Data<State<T>> forSome T是,因为State<*>可以具有不是 的子类型State<Something>。例如,如果您有class State2 extends State<Int>(),则Data<out State<*>>允许Data<State2>,但Data<State<T>> forSome T不会。