为什么Kotlin MAP不变的关键类型参数?
MAP
Kotlin中的接口(使用V1.6.21)具有签名,说明
interface Map<K, out V>
为什么k
不变而不是协变量(OUT K
)?
类型参数的文档k
说:
该地图在其密钥类型中是不变的,因为它可以接受密钥作为参数(例如,例如containskey)并将其返回在键集中。
但是,接口set
在元素类型中是协变量的,因此最后一部分(“以钥匙集返回”)不适用,至少不是立即。
此外,类型参数k
仅在未修改地图状态的出现时使用(方法containskey
, get> get ,<代码> getordefault )。在这些地方,使用@unsafevariance
是否安全?毕竟,将同一技术用于MAP
的值类型参数v
,例如containsValue
,以允许制作v。
协变。
The Map
interface in Kotlin (using V1.6.21) has a signature of
interface Map<K, out V>
Why is K
invariant instead of covariant (out K
)?
The documentation of type parameter K
says:
The map is invariant in its key type, as it can accept key as a parameter (of containsKey for example) and return it in keys set.
However, interface Set
is covariant in the element type, so the the last part ("return it in keys set") is not applicable, at least not immediately.
Further, the type parameter K
is used only at occurrences where the map state is not modified, for lookup purposes (methods containsKey
, get
, getOrDefault
). At these places, isn't it safe to use @UnsafeVariance
? After all, that same technique was employed to Map
's value type parameter V
, for example in containsValue
, to allow making V
covariant.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测是,使用
map&lt; ksubtype,v&gt;
作为map&lt; ksupertype,v&gt;
(其中ksubtype:ksupertype:ksupertype
)不使用确实很有意义,因为前者通过构造无法包含ksubtype
以外的键的条目。因此,适当的实现应从所有调用中返回
null
get(ksupertype)
以及returnfalse
从这些调用到containskey(ksupertype) )
。在
set&lt; out e&gt;
的情况下,只有包含
函数需要不安全的差异,而map
也需要获取。与支持用例的价值相比,这可能是一个独特的支持。
My guess would be that using a
Map<KSubtype, V>
as aMap<KSupertype, V>
(whereKSubtype : KSupertype
) does not really make a lot of sense because the former, by construction, cannot contain entries with keys other thanKSubtype
.So a proper implementation should return
null
from all calls toget(kSupertype)
as well as returnfalse
from those tocontainsKey(kSupertype)
.In the case of
Set<out E>
it's only thecontains
function that needs unsafe variance, andMap
would also require unsafe variance onget
. This might have been too much of a peculiarity to support, compared to the value of supporting the use case.