加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

是否可以在Scala中更改基类/特征的方差?

发布时间:2020-12-16 18:50:23 所属栏目:安全 来源:网络整理
导读:我想从 Scala的不可变映射派生出来.它定义如下: trait Map[A,+B] 不幸的是,我的实现需要在B中保持不变.我尝试了以下内容,但没有成功: def +(kv : (A,B)) : MyMap[A,B] = { ... }override def +[B1 : B](kv : (A,B1)) : MyMap[A,B1] = throw new IllegalArg
我想从 Scala的不可变映射派生出来.它定义如下:

trait Map[A,+B]

不幸的是,我的实现需要在B中保持不变.我尝试了以下内容,但没有成功:

def +(kv : (A,B)) : MyMap[A,B] = { ... }

override def +[B1 >: B](kv : (A,B1)) : MyMap[A,B1] =
    throw new IllegalArgumentException()

也许@uncheckedVariance有一个技巧?

解决方法

完全摆脱协方差当然是不健全的,是不允许的.
给定m:Map [A??,String]和v:Any,你可以做val mm:Map [A??,Any] = m v.这就是Map定义所说的,所有实现者都必须遵循.您的类可能是不变的,但它必须实现Map的完整协变接口.

现在重新定义以抛出错误是一个不同的故事(还不是很健全).新方法的问题在于,在通用擦除之后,它具有与其他方法相同的签名.有一个技巧:添加隐式参数,以便签名中有两个参数,这使得它与第一个不同.

def +(kv : (A,B))(implicit useless: A <:< A) : MyMap[A,B]

(只要找到一个隐式参数,你找的是什么隐式参数并不重要.隐式无用:Ordering [String]的工作原理也一样)

这样做,你有过载的常见问题.如果在没有编译器知道的情况下添加B,则将调用失败的方法.最好在那里执行类型检查,以便接受任何B实例.这需要在地图中获得清单[B].

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读