2012-03-15 5 views
8

내가이 작업을 수행 할 수 있도록하려는 int로 적용 취소 추가스칼라 -

scala> val Int(i) = "1" 
i: Int = 1 

그러나 Intunapply 방법이 없습니다.

기존 개체에 암시 적으로 메서드를 추가하는 방법에 대한 지침을 제공하는 this answer을 발견 했으므로 사용해 보았습니다. 그들이 제공 한 솔루션은 작동하지만, 불행히도 패턴 매칭에는 적합하지 않습니다. 여기에 내가 가진 무엇 :

object UnapplyInt { 
    val IntRE = """^(\d+)$""".r 
    def unapply(v: String): Option[Int] = v match { 
    case IntRE(s) => Some(s.toInt) 
    case _ => None 
    } 
} 
implicit def int2unapplyInt(objA: Int.type) = UnapplyInt 

이 테스트 케이스는 모두 괜찮 :

val UnapplyInt(i) = "1"  // pattern matching with unapply is fine 
val i = Int.unapply("1").get // implicit conversion is fine 

하지만 내가 원하는 하나가 실패 :

scala> val Int(i) = "1" 
<console>:10: error: object Int is not a case class constructor, nor does it have an unapply/unapplySeq method 
     val Int(i) = "1" 
     ^

암시 적 변환 작품과 패턴이 unapply와 일치하는 경우 왜 스칼라는 함축적 인 패턴 매칭을 위해이 두 가지를 함께 사용하지 않는가?

답변

8

편집 그래서 원래의 추론은 좋지 않았습니다. 진짜 이유는 Section 8.1.8 of the Scala language spec입니다

Syntax: 
    SimplePattern ::= StableId ‘(’ [Patterns] ‘)’ 

에서, 추출기 개체가 안정해야하고, 암시 적 변환이 안정되지이다. 추출기가 안정되어야하는 이유에 대한 설명은 없습니다. 생성자이고 패턴 변수가있는 있습니다

... match { 
    foo(bar)(baz) 
} 

지금을 : 나는 스칼라가 빠르게 모호한 될 수 때문에 표현로 추출을 취급하지 않기 때문에이 의심?

다행히이 작업을 수행 할 수 있으며, 그것을 잘 작동합니다 (당신이 주석으로하지만, 다른 문제를 소개) : 유형 Int 및 객체 Int 이후

object Int { 
    def unapply(v: String) = try Some(v.toInt) 
     catch { case _: NumberFormatException => None } 
} 

val Int(i) = "5" 

다른 네임 스페이스에 있습니다.

+0

하! 당신이 제안한 솔루션은 현재 제가 사용하고있는 솔루션입니다. 저는 두 개의 다른 네임 스페이스가 필요하기 때문에 완전히 만족하지 않습니다. 즉 Int.MaxValue와 val Int (i) = "5"를 같은 위치에 둘 수 없습니다. – dhg

+0

@dhg True. 그리고 이제는 그것에 대해 더 많이 생각합니다. 제 대답의 추론이 옳지 않다고 생각합니다. 진짜 이유는 패턴 표현식이 정규식과 같을 수 없다는 것입니다. 왜냐하면 스칼라는 어떤 것이 생성자이고 무엇이 변수인지 식별해야하기 때문입니다 ... – Owen

+1

당신은 그 마지막 부분에서 나를 잃었습니다. 대답에 대해 – dhg