2012-03-15 6 views
8

मैं यह करने के सक्षम होना चाहते हैं:स्काला - unapply जोड़ने Int को

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

लेकिन Int एक unapply विधि नहीं है।

मुझे this answer मिला जो कि किसी मौजूदा ऑब्जेक्ट को विधिवत रूप से जोड़ने का निर्देश देता है, इसलिए मैंने इसे आजमाया। उन्होंने जो समाधान दिया वह दुर्भाग्य से पैटर्न मिलान के लिए नहीं है। यहाँ मैं क्या है: अंतर्निहित रूपांतरण काम करता है और पैटर्न unapply के साथ मिलान हैं

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

:

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 

लेकिन एक मैं चाहता हूँ में विफल रहता है काम करता है, स्कैला इन दो चीजों को एक साथ अंतर्निहित पैटर्न मिलान के लिए क्यों नहीं डालता?

उत्तर

8

संपादित करें तो मेरा मूल तर्क अच्छा नहीं था। असली कारण Section 8.1.8 of the Scala language spec

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

है से, निकालने वस्तु स्थिर हो गया है, और एक अंतर्निहित रूपांतरण स्थिर नहीं है। निकालने वाला क्यों स्थिर होना चाहिए इसके लिए कोई स्पष्टीकरण नहीं दिया गया है; मुझे लगता है ऐसा इसलिए है क्योंकि स्काला एक अभिव्यक्ति के रूप में निकालने के इलाज के लिए क्योंकि है कि जल्दी से अस्पष्ट हो सकता है नहीं चाहता है:

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

अब जो निर्माता है और जो पैटर्न चर रहे हैं?

सौभाग्य से आप यह कर सकते हैं और यह सिर्फ ठीक काम करता है (हालांकि, जैसा कि आप टिप्पणी की, अन्य समस्याओं का परिचय):

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

val Int(i) = "5" 

प्रकार Int और वस्तु Int के बाद से विभिन्न नामस्थान में हैं।

+0

हा! आपका प्रस्तावित समाधान वह है जो मैं वर्तमान में उपयोग कर रहा हूं। मैं इसके साथ पूरी तरह से खुश नहीं हूं क्योंकि इसमें दो अलग-अलग नामस्थान होने की आवश्यकता है, जिसका अर्थ है कि मेरे पास 'Int.MaxValue' और 'Val Int (i) =" 5 "' एक ही स्थान पर नहीं हो सकता है। – dhg

+0

@ डीएचजी ट्रू। और अब जब मैं इसके बारे में और सोचता हूं, तो मुझे लगता है कि मेरे जवाब में तर्क बिल्कुल सही नहीं है। असली कारण यह है कि पैटर्न अभिव्यक्ति नियमित अभिव्यक्तियों की तरह नहीं हो सकती है क्योंकि स्कैला को पहचानना है कि कौन सी चीजें कन्स्ट्रक्टर हैं और क्या चीजें चर हैं ... – Owen

+1

आपने मुझे उस अंतिम भाग पर खो दिया है। – dhg