scala - 无法覆盖具有非 volatile 上限的类型

标签 scala types type-bounds volatility non-volatile

我在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/

相关文章:

syntax - 特征中的 'where' 子句有什么作用?

generics - 如何在 Scala 中的泛型类型上指定 Float 和 Double 的类型绑定(bind)?

java - 如何将 scala.xml.Elem 转换为与 javax.xml API 兼容的东西?

python - 如何从Excel中读取数据并设置数据类型

java - Intellij 中的故障排除 "UNRESOLVED DEPENDENCIES"

list - 在 Dart 中,List.from 和 .of、Map.from 和 .of 之间有什么区别?

types - Common Lisp 类型注释会导致不正常的行为吗?

scala - 为什么类型推断在这里不起作用?

scala - Scala 中 CDATA 中的变量

scala - 对对象列表进行排序的最简单方法