2011-12-15 2 views
5

:: 클래스 (죄수) 정의 된 클래스 List책 "스칼라 프로그래밍"의 제 22 장에서

final case class ::[T](hd: T, tl: List[T]) extends List[T] { 
    //... 
} 

:: 방법으로 정의됩니다

def ::[U >: T](x: U): List[U] = new scala.::(x, this) 

newfinalcaseclass ::의 인스턴스를 만들 필요합니까? 순전히 모호성 제거를위한 것입니까? 당신은 일반 클래스와이 작업을 수행 할 수있는 자동 같은 방식으로, apply 방법 생성자를 호출하는 동반자 개체를 얻을 경우 클래스로

+4

final은 클래스를 확장 할 수 없으며 인스턴스 생성과 관련이 없음을 나타냅니다. 사례 클래스는 기본적으로 '일치 사례'블록에서 비교할 수있는 클래스입니다. – aishwarya

답변

6

: 당신은 new와 케이스 클래스를 인스턴스화 할 수

class Foo(val value: Int) 
object Foo { def apply(value: Int) = new Foo(value) } 

val x = new Foo(42) // 
val y = Foo(42)  // both work the same 

당신이 경우 고 싶어요. 이론적으로는 동반 객체의 apply 메소드를 거치지 않아도되기 때문에 약간 더 빨라질 수도 있지만 빠른 벤치 마크를 시도하고 성능면에서 전혀 차이가없는 것을 보았 기 때문에 컴파일러에 의해 최적화되었거나 그다지 작지는 않습니다. 차이가 실제 건설에 비해.

예를 들어 당신이주는 예제에서 new은 아무런 의미가 없으므로 그냥 생략했을 수도 있습니다.

3

정확합니다. new은 필수 항목이 아닙니다. 그들은 단지뿐만 아니라이 같은 인스턴스 방법 List#::을 정의 할 수 :

def ::[U >: T](x: U): List[U] = scala.::(x, this) 

(우리가 가진 것을 참고 : scala 패키지 객체에 정의

type :: = collection.immutable.:: 
val :: = collection.immutable.:: 

, 첫 번째는 왜 new scala.::(x, this) 작동하고, 두 번째 이유는 내 scala.::(x, this)이 작동하는 이유입니다.)

The form the library uses은 직접 생성자를 호출합니다. 대안은 :: 사례 클래스에 대해 생성 된 합성 동반자 개체의 apply 메서드를 호출합니다.이 메서드는 단순히 생성자를 호출하기 만합니다. 아마도 생성자를 호출하는 것이 더 명확하거나 더 효율적이라고 생각했을 것입니다. (

def ::[U >: T](x: U) = ::(x, this) 

일부 엉뚱한 오인 될 수있다 : (. 컴파일러가 apply에 전화를 인라인하지 않는 경우 때문에 효율 향상이,하지만 아무것도에 가까워 야, JVM은 것) 내가 가장 컴팩트 한 형태를 가정 즉, 불가능한) 재귀 적 호출을 허용하며 어떤 경우 든 :: 클래스와 ::이라는 List 클래스의 구별을 모호하게합니다. Odersky 교수는 독자 이해를 극대화하기 위해 별도로 보관해야합니다.

희망이 도움이됩니다.