根据http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#volatile-types,类型在符合特定条件时会发生变化。是否有可能使类型不易变形(例如通过注释)?有哪些替代方案?
我的用例如下:我想编写一个库,它公开类型A
和B
,其中A <: B
和B
是不稳定的。然后,作为此库的用户,我希望能够使用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
有点人为,我想知道是否还有其他方法。
答案 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"