Kotlin:我怎样才能调用一个lambda字段,它有一个泛型类?

我怎样才能调用一个lambda字段有一个泛型类的类? 出于某种原因,像Example<*>这样的泛型类的引用会产生一个用Nothing代替原始类型(如Example<Something> )的接受。 我怎样才能调用这样一个lambda通过仅参考Example<*>

Codebase我遇到这个问题: https : //github.com/Jire/Acelta/tree/master/src/main/kotlin/com/acelta/packet/incoming/packets

我正在尝试这个代码,但正如你可以看到在第五行我不能调用lambda,因为接受类型是Nothing

 private val incoming = arrayOfNulls<Packet<*>>(256) fun incoming(id: Int, packeteer: Packeteer) { val packet = incoming[id] ?: return packet.receive(packeteer, /* this is type Nothing! */) } 

这种行为就是星形投影 ( Foo<*> )在Kotlin中的工作方式。

正如在文档中所述

对于Foo<T> ,其中T是具有上限TUpper的不变类型参数, Foo<*>相当于读取值的Foo<out TUpper> ,以及写入值的Foo<in Nothing>

如果使用星型投影Packet<*> ,则对泛型类型一无所知,因此您不能安全地将任何值传递给需要泛型参数的方法(这就是为什么Nothing类型)的方法。

您可以使用in-projection为泛型类型指定下限 ,对于Packet<in SomeType>您将能够将SomeType实例SomeType到方法中。 这将需要Packet实际类型参数为SomeType或其某些祖先,类似于? super T Java中的? super T通配符:

 private val incoming = arrayOfNulls<Packet<in SomeType>>(256) fun incoming(id: Int, packeteer: Packeteer) { val packet = incoming[id] ?: return packet.receive(packeteer, someTypeInstance) } 

否则,您可以使用未经检查的转换来调用该方法,尽管它可能导致抛出某处的ClassCastException

 (packet as Packet<in SomeType>).receive(packeteer, someTypeInstance)