2014-02-20 7 views
4

이 작업을 수행 할 수 있습니까?대체 생성자의 고정 유형 매개 변수

final case class C[A] (v: A) { 
    def this() = this(true) 
} 

주어진 생성자로 생성 된 C는 자동으로 C [부울]입니다. 이 버전은 컴파일되지 않습니다하지만 어떻게 든 행할 수 있어야처럼 느낌, 다음이 작동하는 것 같다 특히 :

final case class C[A] (v: A = true) 

내가 어떤 자바 상호 운용성을 원하는, 그래서 기본값을 피하려고합니다. 필자는 동반 객체에서 factory 메소드를 사용하여이 작업을 수행 할 수 있다고 생각하지만 직접 수행 할 수 있습니까? C는 사례 클래스이므로 팩토리 메서드는 다소 지저분한 IMHO입니다. 컴패니언 객체를 사용하는 것이

object C{ 
    def apply() = C(true) 
} 

같은 잘못은 무엇

답변

2

동반자 개체의 팩터 리 방법이 최선이라고 생각합니다 (wheaties 제안). 우리는 그것을 컴파일 할 수 있지만, 어리 석음을 희생해서 줄을서야합니다. 예를 들어 :

final case class C[A] (v: A) { 
    def this() = this("Hello".asInstanceOf[A]) // Compiles, thanks to type erasure 
} 

val c = new C[Int]() // Still compiles, despite the fact that "Hello" is not an Int 
println(c) // C(Hello) 
c.v + 1 // Compiles, but throws a ClassCastException at run-time 

기본적인 문제는 그렇게 모든 생성자가 동일한 유형의 매개 변수를 사용해야합니다, 매개 변수는 클래스 레벨이 아닌 생성자 수준에서 지정되는 유형입니다. 반면에 메서드는 형식 매개 변수를 사용할 수 있으므로 팩터 리 메서드는 문제가되지 않습니다. 또한, 공장 방식에 대한 Java Interop이 그렇게 나쁘지는 않습니다. 스칼라 컴파일러는 일반적으로 C$ 주변에 엉망 필요가 없습니다, 자바 상호 운용성을 단순화하는 정적 메서드를 생성

// C.scala 
final case class C[A] (v: A) 
object C { 
    def apply(): C[Boolean] = C(true) 
} 

// Test.java 
public class Test { 
    public C c = C.apply(); 
} 

: 당신은 뭔가를 할 수 있습니다.

3

? Java의 경우 이것은 C$.apply()일까요?

+0

상당히 못생긴 Java 호출 (IMHO) 외에도 케이스 클래스에 대한 그러한 메소드는 연관된 unapply() 메소드도 (패턴 일치를 위해) 정의해야 함을 암시하는 것처럼 보입니다. 표준 스칼라 코드 스타일입니까? – scand1sk

+1

@ scand1sk'apply '를 정의 할 때'unapply'를 정의 할 필요는 없습니다. 케이스 클래스를위한 두 배. – wheaties