每次Pos
都将被视为一个Ordered[Pos]
,分配将会发生。在某些情况下必须进行分配,请参阅http://docs.scala-lang.org/overviews/core/value-classes.html#when_allocation_is_necessary。
所以当做像调用这样简单的事情时<
,你会得到分配:
val x = Pos( 1 )
val y = Pos( 2 )
x < y // x & y promoted to an actual instance (allocation)
相关规则为(引自上述文章):
每当值类被视为另一种类型(包括通用特征)时,必须实例化实际值类的实例,并且: 此规则的另一个实例是当值类用作类型参数时。
反汇编上面的代码片段证实了这一点:
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
可以看出,我们确实有两个类的“新”操作码实例Position$Pos
更新:为了避免在这样的简单情况下分配,您可以手动覆盖每个方法(即使它们只转发到原始实现):
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)
x < y
通过示例进行时,这将删除分配。但是,这仍然存在Pos
被视为 an的情况Ordered[Pos]
(如传递给采用 aOrdered[Pos]
或 anOrdered[T]
且 T 为类型参数的方法时)。在这种特殊情况下,您仍然会获得分配,并且没有办法解决。