2013-05-14 2 views
9

스칼라의 값 클래스를 프로젝트 중 하나에 적용하고 싶기 때문에 오버 헤드없이 특정 원시 타입을 풍부하게 할 수 있기 때문에 타입 안전성을 유지할 수 있습니다.암시 적 값 클래스의 상속은 오버 헤드를 유발합니까?

object Position { 

    implicit class Pos(val i: Int) extends AnyVal with Ordered[Pos] { 

    def +(p: Pos): Pos = i + p.i 

    def -(p: Pos): Pos = if (i - p.i < 0) 0 else i - p.i 

    def compare(p: Pos): Int = i - p.i 

    } 
} 

내 질문 : 내가 그들을 사용할 때마다Ordered의 상속 (하여 멋진 오버 헤드를 소개합니다) 여부를 Pos 오브젝트의 할당을 강제 할 것인가? 그렇다면이를 피할 수있는 방법이 있습니까?

답변

6

매번 PosOrdered[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에 대한 "새로운"오피 코드의 두 인스턴스

UPDATE해야 할 볼 수 있습니다

다음을 피하기 위해를 할당이 단순한 경우에는 다음과 같이 수동으로 각 메소드를 재정의 할 수 있습니다 (원래 구현에만 전달하더라도).

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은 (a Ordered[Pos] 또는 T는 입력되는 파라미터와 Ordered[T] 복용 방법에 전달 될 때와 같은) Ordered[Pos]로 처리 될 때 그러나, 이것은 여전히 ​​케이스를 남긴다. 이 특별한 경우에, 당신은 여전히 ​​할당을 얻을 것이고, 그 주위에 방법이 없을 것입니다.

+0

당신은 할당을 피하는 방법을 알고 있습니다. Pos를 비교할 수 있습니까? – peri4n

+0

내 업데이트를 확인하십시오. –

+0

대단히 감사합니다. – peri4n

관련 문제