2012-03-15 15 views
8

bunu yapmak mümkün istiyorum int için uygulamasını kaldırma ekleyin:Scala -

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

Ama Int bir unapply yöntemi yoktur.

this answer numaralı belgeyi buldum; bu, varolan bir nesneye dolaylı olarak nasıl bir yöntem ekleyeceğine dair talimatlar veriyor, bu yüzden denedim. Verdikleri çözüm işe yarıyor ama maalesef desen eşleşmesi için değil. İşte ne var:

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 

Bu test durumları hepsi gayet:

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

Ama istediğim biri başarısız:

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" 
     ^

örtük dönüştürme çalışmaları ve desen unapply ile eşleşen ederse Çalışmalar, neden Scala bu iki şeyi örtülü desen eşleştirmesi için bir araya getirmiyor?

cevap

8

düzenleme Bu yüzden orijinal nedenlerim iyi değildi. Gerçek nedeni Section 8.1.8 of the Scala language spec olduğunu

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

itibaren çıkarıcı nesne kararlı olmalı, ve bir örtük dönüştürme stabil olmaması. Aspiratörün neden kararlı olması gerektiğine dair bir açıklama yapılmamıştır; yapıcı ve desen değişkenleri hangi vardır

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

Now: Ben Scala o hızla belirsiz hale gelebilir çünkü ifadesi olarak çıkarıcı tedavi etmek istemiyor çünkü şüpheli?

Neyse ki bunu yapabilirsiniz ve gayet güzel çalışıyor (siz yorum olarak olsa da, başka sorunları da getirmektedir): tip Int ve nesne Int beri

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

val Int(i) = "5" 

başka ad boşluklarında bulunan.

+0

Ha! Önerilen çözüm şu anda kullandığım şey. Onunla tamamen mutlu değilim çünkü iki farklı ad alanına sahip olmanızı gerektiriyor, yani aynı yerde Int.MaxValue ve val (Int (i) = "5" 'e sahip olamayacağım anlamına geliyor. – dhg

+0

@dhg True. Ve şimdi bunun hakkında daha fazla düşünüyorum, bence cevabımdaki mantık doğru değil. Asıl neden, kalıp ifadelerinin normal ifadeler gibi olamayacağıdır, çünkü Scala'nın yapıcıların ne olduğunu ve hangi şeylerin değişken olduğunu tanımlaması gerekir ... – Owen

+1

Beni bu son bölümde kaybettin. Cevabınız için – dhg