2013-11-03 17 views
16

के लिए पैटर्न मिलान "केस नील" postVector पर पैटर्न मिलान का उपयोग करने के तरीके (या Seq लागू करने वाले किसी भी संग्रह) को पढ़ने के बाद, मैंने इस संग्रह पर पैटर्न मिलान का परीक्षण किया।वेक्टर

object +: { 
    def unapply[T](s: Seq[T]) = 
    s.headOption.map(head => (head, s.tail)) 
} 

REPL मुझे पता चलता है कि

scala> Vector[Int]() == Nil 
res37: Boolean = true 

... तो क्यों मैं एक Vector के लिए इस case Nil कथन का उपयोग नहीं कर सकते हैं:

scala> x // Vector 
res38: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3) 

scala> x match { 
    | case y +: ys => println("y: " + "ys: " + ys) 
    | case Nil => println("empty vector") 
    | } 
<console>:12: error: pattern type is incompatible with expected type; 
found : scala.collection.immutable.Nil.type 
required: scala.collection.immutable.Vector[Int] 
Note: if you intended to match against the class, try `case _: <none>` 
       case Nil => println("empty vector") 
        ^

यहाँ dhg के जवाब यह है कि +: बताते है?

उत्तर

24

तुलना Vector[Int]() == Nil संभव है क्योंकि आप तुलना करने के लिए प्रकार के स्तर पर कोई बाधा नहीं है; कि equals के कार्यान्वयन संग्रह के लिए, दूसरे हाथ पर, एक तत्व तत्व तुलना द्वारा ध्यान दिए बिना संग्रह प्रकार का प्रदर्शन करने के लिए अनुमति देता है:

Vector(1, 2, 3) == List(1, 2, 3) // true! 

पैटर्न मिलान में, आप एक खाली सूची के लिए एक मामला नहीं हो सकता (Nil) जब प्रकार सूची से संबंधित नहीं है (यह Vector है)।

आप इस हालांकि कर सकते हैं:

val x = Vector(1, 2, 3) 

x match { 
    case y +: ys => println("head: " + y + "; tail: " + ys) 
    case IndexedSeq() => println("empty vector") 
} 

लेकिन मैं यहाँ डिफ़ॉल्ट मामले उपयोग करने के लिए है, क्योंकि x एक सिर तत्व नहीं है, तो सुझाव है, यह तकनीकी रूप से खाली नहीं होना चाहिए:

x match { 
    case y +: ys => println("head: " + y + "; tail: " + ys) 
    case _ => println("empty vector") 
} 
+0

इस उत्तर के लिए धन्यवाद। एक तरफ फॉलो-अप के रूप में, पैटर्न मिलान में "कैच-ऑल" '_' का उपयोग करना आम तौर पर एक अच्छी या बुरी आदत है? मैं आपके शब्दों में, यहां से '_' का उपयोग करने के आपके कारण को समझता हूं, "लेकिन मैं केवल डिफ़ॉल्ट मामले का उपयोग करने का सुझाव दूंगा, क्योंकि यदि एक्स में कोई मुख्य तत्व नहीं है, तो यह तकनीकी रूप से खाली होना चाहिए।" –

+2

कैच सभी आपके विचार से गलती से अधिक मामलों को पकड़ सकते हैं। स्पष्ट रूप से समेकित (मुहरबंद) प्रकारों के लिए मैं सुझाव दूंगा कि '_' का उपयोग न करें। उदाहरण के लिए, 'सूची' के साथ आपके पास कंपाइलर चेक है: 'def foo (xs: list [Any]) = xs match {case head :: tail => "yes"}' आपको चेतावनी देता है, 'def foo (xs: वेक्टर [कोई भी]) = एक्सएस मैच {केस हेड +: पूंछ => "हाँ"} 'नहीं। 'सूची' के लिए मैं अनुक्रमित वर्ग 'केस _' के लिए' केस नील 'का उपयोग करूंगा ... –