我想知道在这种特殊情况下如何正确使用in / out方差修饰符。
我有一个具有特定实现类型的通用Map
,我想将其分配给更通用的类型下的一个变量:
var generalMap: Map<SimpleExpression<Any>, Any> = emptyMap()
var specificMap: Map<StringExpression, String?> = makeSomeMap()
generalMap = specificMap // this assignment won't compile :(
同样,
StringExpression
扩展了SimpleExpression<String>
。我已经尝试过用out
方差修饰符在generalMap
定义上进行几种不同的方式:var generalMap: Map<out SimpleExpression<Any>, out Any?> = emptyMap()
...但不幸的是遇到了相同的编译器错误。
最佳答案
仅当SimpleExpression<T>
仅产生 T值时,才可以进行这种分配。如果是这样,请按照以下说明进行接口(interface)或类的声明:
interface SimpleExpression<out T>
接下来需要更改的是
generalMap
的声明。将out
方差添加到SimpleExpression<..>
中,并使Any
可为空:var generalMap: Map<out SimpleExpression<Any>, Any?> = emptyMap()
之后,编译器允许您安全地将
specificMap
分配给generalMap
。如果还生成并使用了
T
中的SimpleExpression
(具有fun consume(t: T)
和fun produce(): T
之类的方法),则应这样声明generalMap
:var generalMap: Map<out SimpleExpression<*>, Any?> = emptyMap()