Za każdym razem Pos
będzie traktowany jako Ordered[Pos]
, nastąpi przydzielenie. Istnieje kilka przypadków, kiedy przydział musi nastąpić, patrz http://docs.scala-lang.org/overviews/core/value-classes.html#when_allocation_is_necessary.
Więc kiedy robi coś tak prostego jak wywołanie <
, dostaniesz przydział:
val x = Pos(1)
val y = Pos(2)
x < y // x & y promoted to an actual instance (allocation)
Odpowiednie przepisy zostały (cytat z powyższego artykułu):
Ilekroć klasa wartość jest traktowana jako inny typ, w tym cechę uniwersalną, instancja klasy wartości rzeczywistej musi być utworzona i: Innym przykładem tej reguły jest użycie klasy wartości jako argumentu typu.
Demontaż powyższy fragment kodu potwierdza:
0: aload_0
1: iconst_1
2: invokevirtual #21 // Method Pos:(I)I
5: istore_1
6: aload_0
7: iconst_2
8: invokevirtual #21 // Method Pos:(I)I
11: istore_2
12: new #23 // class test/Position$Pos
15: dup
16: iload_1
17: invokespecial #26 // Method test/Position$Pos."<init>":(I)V
20: new #23 // class test/Position$Pos
23: dup
24: iload_2
25: invokespecial #26 // Method test/Position$Pos."<init>":(I)V
28: invokeinterface #32, 2 // InterfaceMethod scala/math/Ordered.$less:(Ljava/lang/Object;)Z
Jak widać mamy dwie instancje „nowej” opcode dla klasy Position$Pos
UPDATE: aby uniknąć przydział w takich przypadkach jak w przypadku uproszczeń, można ręcznie zastąpić każdą metodę (nawet jeśli przesyłają tylko do początkowej implementacji):
override def < (that: Pos): Boolean = super.<(that)
override def > (that: Pos): Boolean = super.>(that)
override def <= (that: Pos): Boolean = super.<=(that)
override def >= (that: Pos): Boolean = super.>=(that)
Spowoduje to usunięcie przydziału po wykonaniu przykładu x < y
. Jednak nadal pozostawia przypadki, gdy Pos
jest traktowane jako Ordered[Pos]
(jak po przekazaniu do metody przyjmującej Ordered[Pos]
lub Ordered[T]
z T będącym parametrem typu). W tym konkretnym przypadku nadal otrzymasz alokację i nie da się tego obejść.
Czy znasz jakiś sposób, aby uniknąć przydziału, aby marka Pos była porównywalna? – peri4n
Sprawdź moją aktualizację. –
Dziękuję bardzo – peri4n