我在scala中遇到编译器错误,我不知道它指的是什么:
假设这些声明:
trait Abstract {
type MyType
}
trait AInner
trait A extends Abstract{
type MyType <: AInner
}
trait BInner {
def bMethod : Int
}
trait B extends Abstract with A{
override type MyType <: BInner with A#MyType
}
我要在此处实现的目的(在trait B
中)是进一步限制在MyType
中声明的Abstract
类型,因此MyType
类型的任何值都必须扩展mixin树中的所有MyType
。编译器给我这个消息(如标题所示):
MyType类型是 volatile 类型;无法覆盖具有非 volatile 上限的类型。我了解,由于类型共轭
with A#MyType
,此处发生了类型易变性,这是错误的一部分:带有非 volatile 上限的类型可能引用了类型声明type MyType <: AInner
,其中AInner
不是抽象类型,因此不是易 volatile 的。我为什么不能这样做?有没有办法实现我的目标?
最佳答案
删除编译器中的此检查,使我们可以发现出现不健全的可能性。
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 37a7e3c..78a8959 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -5128,8 +5128,7 @@ trait Typers extends Adaptations with Tags {
def typedSelectFromTypeTree(tree: SelectFromTypeTree) = {
val qual1 = typedType(tree.qualifier, mode)
- if (qual1.tpe.isVolatile) TypeSelectionFromVolatileTypeError(tree, qual1)
- else typedSelect(tree, qual1, tree.name)
+ typedSelect(tree, qual1, tree.name)
}
def typedTypeBoundsTree(tree: TypeBoundsTree) = {
然后,从编译器测试用例运行代码,以对volatile类型进行非法类型选择:
scala> class A; class B extends A
defined class A
defined class B
scala> trait C {
| type U
| trait D { type T >: B <: A }
| val y: (D with U)#T = new B
| }
defined trait C
scala> class D extends C {
| trait E
| trait F { type T = E }
| type U = F
| def frob(arg : E) : E = arg
| frob(y)
| }
defined class D
scala> new D
java.lang.ClassCastException: B cannot be cast to D$E
据我了解,问题源于Scala没有真正的交集类型。
scala> type A = { type T = Int }
defined type alias A
scala> type B = { type T = String }
defined type alias B
scala> "": (A with B)#T
res16: String = ""
scala> 0: (A with B)#T
<console>:37: error: type mismatch;
found : Int(0)
required: String
0: (A with B)#T
^
如果对Dependent Object Types (DOT)的研究取得成果,那么将来可能会改变。
关于scala - 无法覆盖具有非 volatile 上限的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15880438/