为什么Kotlin Map的key类型参数是不变的?



Kotlin中的Map接口(使用V1.6.21)有一个签名

interface Map<K, out V>

为什么K不变而不是协变(out K)?

类型参数K的文档说:

map的键类型是不变的,因为它可以接受key作为参数(例如containsKey),并在keys set中返回它。

但是,接口Set在元素类型中是协变的,因此最后一部分("在keys set"中返回它")不适用,至少不是立即适用。

此外,类型参数K仅在未修改映射状态的情况下使用,用于查找目的(方法containsKey,get,getOrDefault)。在这些地方,使用@UnsafeVariance不是很安全吗?毕竟,Map的值类型参数V也采用了同样的技术,例如在containsValue中,允许V协变。

我的猜测是,使用Map<KSubtype, V>作为Map<KSupertype, V>(其中KSubtype : KSupertype)并没有多大意义,因为前者根据构造不能包含除KSubtype以外的键项。

所以一个正确的实现应该从所有对get(kSupertype)的调用中返回null,从那些对containsKey(kSupertype)的调用中返回false

Set<out E>的情况下,只有contains函数需要不安全方差,Map也需要get的不安全方差。与支持用例的价值相比,这可能是太多的特性来支持了。

相关内容

  • 没有找到相关文章

最新更新