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

Scala – 覆盖带有边界的类型成员

发布时间:2020-12-16 18:10:15 所属栏目:安全 来源:网络整理
导读:我在 Scala代码中的特征层次结构存在以下问题: 首先,我有一个基本特征MyTrait [A]具有这样的定义: trait MyTrait[A] { def v1: A} 然后是一个带有类型成员的特征Base的定义: trait Base[A] { type T : MyTrait[A] val baseV: T} 最后,一个特性Gen覆盖Base
我在 Scala代码中的特征层次结构存在以下问题:

首先,我有一个基本特征MyTrait [A]具有这样的定义:

trait MyTrait[A] {
  def v1: A
}

然后是一个带有类型成员的特征Base的定义:

trait Base[A] {
  type T <: MyTrait[A]
  val baseV: T
}

最后,一个特性Gen覆盖Base的类型成员.

trait Gen[A,X <: MyTrait[A]] extends Base[A] {
  type T = X
}

问题是,在Gen特征中,似乎类型成员的边界丢失了.这可以通过以下测试证明:

编译:

trait Test1 {
  val x: Base[_]
  println(x.baseV.v1)
}

不编译(值v1不是Test2.this.x.T的成员):

trait Test2 {
  val x: Gen[_,_]
  println(x.baseV.v1)
}

我想知道这是语言的限制还是有解决方法.关于stackowerflow(1,2)上类似主题的问题似乎集中在与我不同的方面,我真的不知所措,因为我无法在Scala中找到有关此类行为的更多信息.

可以在scastie找到此问题的Scala代码模板

解决方法

这有效:

trait Test2 {
  val x: Gen[A,X] forSome { type A; type X <: MyTrait[A] }
  println(x.baseV.v1)
}

我相信问题是这样的

Gen[_,_]

Has to mean

Gen[_ >: Nothing <: Any,_ >: Nothing <: Any]

哪个是一样的

Gen[A,X] forSome { type A; type X }

也就是说,即使Gen的界限表示X&lt ;: MyTrait [A],通配符也不会继承该界限.你可以在这里看到类似的问题:

trait Data { def data: String }
trait Box[A <: Data] { def data: A }
def unbox(b: Box[_]): String = b.data.data // nope; the wildcard is not <: Data

我们可以明确地将通配符添加到通配符.但是,因为第二个通配符上的绑定取决于第一个通配符,所以我们不得不对存在主义使用扩展的forSome语法,因此我们可以命名A并使用它两次.

Gen[A,_ <: MyTrait[A]] forSome { type A }

我选择将所有内容都放在存在主义条款中,这相当于:

Gen[A,X] forSome { type A; type X <: MyTrait[A] }

你也可以使用

Gen[_,_ <: MyTrait[_]]

但这不等同,因为它与左右参数无关.如果Gen [A,_]除MyTrait [A]外还包含A,则使用x:Gen [_,_&lt ;: MyTrait [_]]将呈现“裸”值和“包裹”值不兼容的类型.

(编辑:李大同)

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

    推荐文章
      热点阅读