Według http://www.scala-lang.org/files/archive/spec/2.11/03-types.html#volatile-typestypy są niestabilne, gdy spełniają określone warunki. Czy można uczynić typ lotnym (np. Przez adnotację), który nie jest w tej formie? Jakie są możliwe alternatywy?
Mój przypadek użycia jest następujący: chcę napisać bibliotekę, która ujawnia typy A
i B
z A <: B
i B
jest niestabilny. Następnie jako użytkownik tej biblioteki chcę mieć możliwość nadpisania wartości typu A
z jednym typem 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 = ???
}
}
Nie powiedzie się z powodu błędu:
błąd: przesłanianie wartości x w cechy T typu LibraryUser.library.A; wartość x ma typ ulotny; nie może zastąpić elementu członkowskiego nieulotnym typem
Ale kiedy robię A
niestabilna, to się powiedzie. Obecnie robię A
niestabilna, czyniąc ją podklasą typu abstrakcyjnego Abstract
który po prostu będzie Any
w realizacji i w inny sposób nieużywany:
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 = ???
}
}
To kompiluje się i działa dobrze, ale Abstract
jest trochę sztuczna i zastanawiam się, czy jest inny sposób.
Odpowiedzi:
-1 dla odpowiedzi nr 1Szukasz @volatile
adnotacja, co pozwoli kompilatorowi poznać plik var
powinien być niestabilny. Powinien zachowywać się tak samo, jak równoważna adnotacja Java.
Możemy to udowodnić, budując prostą klasę w pliku SoVolatile.scala
:
class SoVolatile {
@volatile var boom = 5
}
Następnie w wierszu poleceń przejdź do katalogu z tą klasą i uruchom:
$ scalac SoVolatile.scala
$ javap -verbose -private SoVolatile
Wewnątrz znajdujemy linię private volatile int boom;
. Jest to trochę łatwiejsze do znalezienia, jeśli uruchomisz to w wierszu poleceń:
$ javap -verbose -private SoVolatile | grep "private volatile"