如何在kotlin中将通用映射指定为超类
我想知道如何在这个特定的情况下正确使用in / out方差修饰符。
我有一个具有特定的实现types的genericsMap
,我想分配给一个更通用的types的variables:
var generalMap: Map<SimpleExpression, Any> = emptyMap() var specificMap: Map = makeSomeMap() generalMap = specificMap // this assignment won't compile :(
而且, StringExpression
扩展了SimpleExpression
。 我试过在generalMap
定义中使用差异修饰符来修改一些不同的方法:
var generalMap: Map<out SimpleExpression, out Any?> = emptyMap()
…但不幸的是跑到相同的编译器错误。
只有当SimpleExpression
只产生 T值时,这种赋值才是可能的。 如果是这样,请将您的接口或类声明如下所示:
interface SimpleExpression
接下来你必须改变它是generalMap
声明。 将方差添加到SimpleExpression<..>
并使Any
null:
var generalMap: Map, Any?> = emptyMap()
之后,编译器允许您安全地将specificMap
分配给generalMap
。
如果SimpleExpression
T
被生成和使用(像fun consume(t: T)
这样的方法fun consume(t: T)
和fun produce(): T
),那么你应该像下面这样声明generalMap
:
var generalMap: Map, Any?> = emptyMap()
Map
不是关键types的变体,因为它in
.get()
和.keys()
位置都.keys()
。 把它当作out
是不安全的,因为
var specificMap: Map = makeSomeMap() var generalMap: Map, Any> = specificMap generalMap[intExpression] // specificMap.get(not a StringExpression)
也就是说,如果您认为这不会导致makeSomeMap()
返回的特定Map
实现的任何实际问题,那么没有任何东西阻止您进行未经检查的makeSomeMap()
。