如何使scala类型有意挥发

时间:2016-05-27 22:32:56

标签: scala types

根据http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#volatile-types,类型在符合特定条件时会发生变化。是否有可能使类型不易变形(例如通过注释)?有哪些替代方案?

我的用例如下:我想编写一个库,它公开类型AB,其中A <: BB是不稳定的。然后,作为此库的用户,我希望能够使用A类型的值覆盖B类型的值:

trait TraitB {
  def doSomething: Unit
}

trait Library {
  type A
  type B <: A with TraitB
}

object LibraryUser {
  val library: Library = ???

  trait T {
    val x: library.A
  }

  object U extends T {
    val x: library.B = ???
  }
}

失败并显示错误:

  

错误:覆盖类型LibraryUser.library.A的特征T中的值x;   值x具有易失性类型;不能覆盖非易失性类型的成员

但是当我使A变得不稳定时,这就成功了。目前,我通过使A为抽象类型Abstract的子类来实现Any volatile,它在实现中只是trait TraitB { def doSomething: Unit } trait Library2 { protected type Abstract type A <: Any with Abstract type B <: A with TraitB } trait Library2ImplementationHelper { this: Library2 => override type Abstract = Any } object Library2User { val library: Library2 = ??? trait T { val x: library.A } object U extends T { val x: library.B = ??? } } ,否则不会使用:

Abstract

这编译并且工作正常,但是templates有点人为,我想知道是否还有其他方法。

1 个答案:

答案 0 :(得分:-2)

您正在寻找@volatile annotation,这将让编译器知道var应该是易失性的。它的行为应该与等效的Java注释相同。

我们可以通过在文件SoVolatile.scala中构建一个简单的类来证明这一点:

class SoVolatile {
  @volatile var boom = 5
}

然后在命令行上,转到该类的目录并运行:

$ scalac SoVolatile.scala
$ javap -verbose -private SoVolatile

在里面我们找到了行private volatile int boom;。如果您在命令行上运行它,则更容易找到:

$ javap -verbose -private SoVolatile | grep "private volatile"