scala – 依赖于路径的类型 – 以下代码有什么问题?
发布时间:2020-12-16 18:48:55 所属栏目:安全 来源:网络整理
导读:以下代码: trait Foo { type T val x: T}trait Bar { type F : Foo { type T : F }}class C[B : Bar](val f: B#F) { val x: f.T = f.x} 被Scala编译器(2.11.5)拒绝,并显示以下错误消息: error: type mismatch;found : C.this.f.x.type (with underlying ty
以下代码:
trait Foo { type T val x: T } trait Bar { type F <: Foo { type T <: F } } class C[B <: Bar](val f: B#F) { val x: f.T = f.x } 被Scala编译器(2.11.5)拒绝,并显示以下错误消息: error: type mismatch; found : C.this.f.x.type (with underlying type C.this.f.T) required: this.T val x: f.T = f.x ^ 如果省略显式类型声明,则根据typer阶段的输出正确推断类型: private[this] val x: C.this.f.T = C.this.f.x; <stable> <accessor> def x: C.this.f.T = C.this.x 如果Bar中的边界内的F更改为不是Bar成员的类型,则问题也会消失,即 type F <: Foo { type T <: Foo } 工作正常. 这是一个错误吗?或者我的一些根本误解?还是一些神秘的功能? 解决方法
不是一个明确的答案,但有些观察……
让我们先看看有什么用: class C[B <: Foo](val f: B) { val x: f.T = f.x } 因此,当使用值f的类型投影时,编译器会丢失.如果您“修复”该投影,它似乎也有效: class D[B <: Bar](val f: B#F) { val g: Foo = f val x: g.T = g.x } 我一直在与F-bounded类型斗争,直到我让它们“防水”.类型参数与类型成员之间存在一些使前者工作的东西.例如: trait FooRec[F <: FooRec[F]] extends Foo { type T = F } class E[F <: FooRec[F]](val f: F) { val x: f.T = f.x } 最后,您还可以通过将其作为类型参数传入来修复Bar的类型成员: class G[F1 <: Foo { type T = F1 },B <: Bar { type F = F1 }](val f: B#F) { val x: f.T = f.x } 类似地,如果你修改了Bar的定义中已经存在的类型,它可以工作: trait Baz { type F <: Foo { type T = F } // stable recursion } class H[B <: Baz](val f: B#F) { val x: f.T = f.x } 所以在你的原始定义和应用程序中有上限似乎是不够的.可能你可以证明编译器对它的拒绝是正确的,但我不知道如何…… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |