Generics 如何在kotlin中将泛型映射指定为超类

Generics 如何在kotlin中将泛型映射指定为超类,generics,kotlin,Generics,Kotlin,我想知道在这种特殊情况下如何正确使用in/out方差修饰符 我有一个带有特定实现类型的泛型映射,我想将其分配给更泛型类型下的变量: var generalMap: Map<SimpleExpression<Any>, Any> = emptyMap() var specificMap: Map<StringExpression, String?> = makeSomeMap() generalMap = specificMap // this assignm

我想知道在这种特殊情况下如何正确使用in/out方差修饰符

我有一个带有特定实现类型的泛型
映射
,我想将其分配给更泛型类型下的变量:

var generalMap: Map<SimpleExpression<Any>, Any> = emptyMap()
var specificMap: Map<StringExpression, String?> = makeSomeMap()

generalMap = specificMap // this assignment won't compile :(

…但不幸的是,遇到了相同的编译器错误。

映射
不是键类型的变体,因为它出现在
中的
位置到
.get()
中取出
位置。将其视为
out
是不安全的,因为

var specificMap: Map<StringExpression, String?> = makeSomeMap()
var generalMap: Map<SimpleExpression<Any>, Any> = specificMap
generalMap[intExpression]  // specificMap.get(not a StringExpression)
var specificMap:Map=makeSomeMap()
var generalMap:Map=specificMap
generalMap[intExpression]//specificMap.get(不是StringExpression)

也就是说,如果您认为这不会导致
makeSomeMap()

Map
返回的特定
Map
实现出现任何实际问题,那么没有什么可以阻止您进行未经检查的强制转换,因为它在
位置和
out
.keys()
定位。将其视为
out
是不安全的,因为

var specificMap: Map<StringExpression, String?> = makeSomeMap()
var generalMap: Map<SimpleExpression<Any>, Any> = specificMap
generalMap[intExpression]  // specificMap.get(not a StringExpression)
var specificMap:Map=makeSomeMap()
var generalMap:Map=specificMap
generalMap[intExpression]//specificMap.get(不是StringExpression)

也就是说,如果您认为这不会导致
makeSomeMap()

返回的特定
Map
实现出现任何实际问题,那么没有任何东西可以阻止您进行未经检查的强制转换。只有当
SimpleExpression
仅生成T值时,这种赋值才可能。如果是这样,请按照以下说明进行接口或类声明:

interface SimpleExpression<out T> 
之后,编译器允许您将
specificMap
安全地分配给
generalMap

如果
SimpleExpression
中的
T
也被生成和使用(有
fun-consume(T:T)
fun-product():T
等方法),那么您应该像这样声明
generalMap

var generalMap: Map<out SimpleExpression<*>, Any?> = emptyMap()
var generalMap:Map=emptyMap()

只有当
SimpleExpression
仅产生T值时,才可能进行这种赋值。如果是这样,请按照以下说明进行接口或类声明:

interface SimpleExpression<out T> 
之后,编译器允许您将
specificMap
安全地分配给
generalMap

如果
SimpleExpression
中的
T
也被生成和使用(有
fun-consume(T:T)
fun-product():T
等方法),那么您应该像这样声明
generalMap

var generalMap: Map<out SimpleExpression<*>, Any?> = emptyMap()
var generalMap:Map=emptyMap()