Scala – 覆盖带有边界的类型成员
我在
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< ;: 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 [_,_< ;: MyTrait [_]]将呈现“裸”值和“包裹”值不兼容的类型. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |