2011-09-01 6 views
13
에 카레 생성자 그들은 그 잘 혼합하지 않는 것

: 문제는 그 패턴 매칭이다케이스 클래스, 패턴 매칭 및 스칼라

B(1)("1") match { 
    case B(a)(b) => print("B") 
    case C() => print("C") 
} 

과 :

abstract class A 
case class B (var a: Int)(var b: String) extends A 
case class C extends A 

다음은 작동하지 않습니다 카레트 인자는 효과가없는 것처럼 보입니다. 이 문제를 해결할 수 있습니까?

답변

7

무엇이 문제입니까?

def m(a: A) = a match { 
    case b: B => print("B") 
    case c: C => print("C") 
} 

나는 이것보다 많은 기능을 요구하지 않았기 때문에 묻습니다.

편집

이 도움이 될 수 :

object Dog { 
    def apply(name: String)(size: Int) = new Dog(name)(size) 
    def unapply(dog: Dog) = Some(dog.name, dog.size) 
} 
class Dog(val name: String)(var size: Int) 

지금 당신도 같은 개를 만들 수 있습니다

Dog("Snoopy")(10) 
0 :
new Dog("Snoopy")(10) 

또는 같은 하지만 개 패턴 매칭시 생성자 패턴은 이 아니며은 카레입니다. unapply(x$0: Q): Option[Int] : 당신은 클래스 B를 위해 만든 적용 취소 함수의 서명을 보면

Dog("Snoopy")(10) match { 
    case Dog(a, b) => // do sth with a or b 
} 
+0

첫 번째 예제가 작동하지만 추악한 typecasting을 수행하지 않고 case 문에서 B.a 및 B.b에 액세스 할 수 없습니다. 또한 편집 할 때 왜 생성자 패턴이 카레되지 않았는지 알지 못합니다. 적용을 취소했기 때문입니까? –

+0

솔직하게 나는 왜 그것이 작동하는지 전혀 모른다. 나는 시행 착오를 통해 그것을 우연히 발견했다. 이것은 Scala 사양의 어딘가에서 확실히 언급됩니다. 귀하의 사건과 관련이 있다면 그것을 찾아보고 싶을 수도 있습니다. – agilesteel

+1

예, case 문에서 사용하는 패턴은 적용 취소 함수의 결과로 제공되는 패턴입니다. 그것은 결코 카레 될 수 없다. 스칼라 스펙의 해당 섹션은 §8.1.8입니다. – Nicolas

2

일반 사례 클래스를 사용할 수 있으며 둘 이상의 매개 변수 목록이있는 팩터 리 메서드 만 정의 할 수 있습니다.

+0

팩터 리 메소드는 companion 객체에서 선언 된 경우 ('t'와 동일한 지우기가 있기 때문에) '적용'할 수 없다고 추가 할 수 있습니다. e 사례 클래스에 감사함). – Nicolas

11

, 당신은 것을 볼 수 있습니다. 따라서 unapply 함수는 case 클래스의 매개 변수의 첫 번째 범위에서 작동합니다.

이것은 스칼라 사양 (§5.3.2)에 의해 확인된다

경우 클래스 의 인터넷 RST 파라미터 부의 형식 매개

이 요소라고; 그들은 특별히 대우받습니다. 먼저, 그러한 파라미터의 값은 의 값이 생성자 패턴의 필드로서 추출 될 수있다.

첫 번째 매개 변수 섹션 만 추출기를 통해 사용할 수 있음이 분명합니다.

몇 가지 해결 방법 : 당신의 매개 변수 uncurry

  • 당신이이 개 값을 테스트하려는 경우 가드와 일치하는 패턴을 사용 : case [email protected](3) if x.b == "bazinga" => ...
  • 가 정상 클래스를 사용하여 자신의 동반자 객체를 정의 당신의 자신의 apply/unapply