2012-01-09 25 views
18

मैं समझने की कोशिश कर रहा हूं कि स्काला केस क्लासेस के साथ क्या करता है जो उन्हें किसी भी प्रकार की मिटा चेतावनी टाइप करने के लिए प्रतिरक्षा बनाता है।स्कैला: केस क्लास अनप्ली बनाम मैन्युअल कार्यान्वयन और टाइप एरर

मान लें कि हमारे पास निम्न, सरल वर्ग संरचना है। यह मूल रूप से एक Either है:

abstract class BlackOrWhite[A, B] 

case class Black[A,B](val left: A) extends BlackOrWhite[A,B] 

case class White[A,B](val right: B) extends BlackOrWhite[A,B] 

और तुम इस तरह इसका इस्तेमाल करने की कोशिश कर रहे हैं:

object Main extends App { 

    def echo[A,B] (input: BlackOrWhite[A,B]) = input match { 
     case Black(left) => println("Black: " + left) 
     case White(right) => println("White: " + right) 
    } 

    echo(Black[String, Int]("String!")) 
    echo(White[String, Int](1234)) 
} 

सब कुछ संकलित करता है तथा बिना किसी समस्या के चलाता है। हालांकि, जब मैं unapply विधि को स्वयं लागू करने का प्रयास करता हूं, तो संकलक चेतावनी फेंकता है।

abstract class BlackOrWhite[A, B] 

case class Black[A,B](val left: A) extends BlackOrWhite[A,B] 

object White { 

    def apply[A,B](right: B): White[A,B] = new White[A,B](right) 

    def unapply[B](value: White[_,B]): Option[B] = Some(value.right) 

} 

class White[A,B](val right: B) extends BlackOrWhite[A,B] 

संकलन कि -unchecked झंडा मुद्दों निम्न चेतावनी के साथ:

[info] Compiling 1 Scala source to target/scala-2.9.1.final/classes... 
[warn] src/main/scala/Test.scala:41: non variable type-argument B in type pattern main.scala.White[_, B] is unchecked since it is eliminated by erasure 
[warn]   case White(right) => println("White: " + right) 
[warn]     ^
[warn] one warning found 
[info] Running main.scala.Main 

अब, मैं प्रकार विलोपन को समझते हैं और मैं करने के लिए कोशिश की है मैं ऊपर ही Main वर्ग के साथ निम्न वर्ग संरचना का इस्तेमाल किया Manifests (अभी तक कोई फायदा नहीं हुआ) के साथ चेतावनी के आसपास जाओ, लेकिन दो कार्यान्वयन के बीच क्या अंतर है? क्या केस क्लास ऐसा कुछ कर रहे हैं जिसमें मुझे जोड़ने की ज़रूरत है? क्या इसे Manifests से घिराया जा सकता है?

मैं भी -Xprint:typer ध्वज के साथ स्केला संकलक के माध्यम से मामले वर्ग कार्यान्वयन चल चालू कोशिश की, लेकिन unapply विधि काफी है कि मैं उम्मीद दिखता है:

case <synthetic> def unapply[A >: Nothing <: Any, B >: Nothing <: Any](x$0: $iw.$iw.White[A,B]): Option[B] = if (x$0.==(null)) 
    scala.this.None 
else 
    scala.Some.apply[B](x$0.right); 

अग्रिम धन्यवाद

+0

आप कर रहे हैं स्कैला के नवीनतम संस्करण का उपयोग करके? मैं आपकी समस्या को पुन: पेश नहीं कर सकता, और कुछ महीने पहले इस संबंधित प्रश्न ने आपके लिए एक संकलक बग के रूप में एक समान समस्या निर्धारित की। http://stackoverflow.com/questions/7008428/difference देखें -बेटवीन-होम-निर्मित-एक्स्ट्रैक्टर-एंड-केस-क्लास-एक्सट्रैक्टर – Destin

+0

मैं 2.9.1.फिनल (Xubuntu 11.10 पर, यदि यह मायने रखता है) का उपयोग कर रहा है – Nycto

उत्तर

12

मैं नहीं कर सकता एक पूर्ण उत्तर दें, लेकिन मैं आपको बता सकता हूं कि संकलक केस कक्षाओं के लिए unapply विधि उत्पन्न करता है, भले ही यह पैटर्न किसी केस क्लास पर मेल खाता हो, यह उस अनुपयुक्त विधि का उपयोग नहीं करता है। यदि आप बिल्टिन केस मिलान और unapply विधि दोनों का उपयोग करके -Ybrowse:typer आज़माते हैं, तो आप उपयोग किए जाने के आधार पर एक बहुत ही अलग वाक्यविन्यास पेड़ (match के लिए) देखेंगे। आप बाद के चरणों को भी ब्राउज़ कर सकते हैं और देख सकते हैं कि अंतर बनी हुई है।

क्यों स्कैला अंतर्निहित रूप से बिल्टिन का उपयोग नहीं करता है, मुझे यकीन नहीं है, हालांकि यह आपके कारण के कारण हो सकता है। और अपने unapply के लिए इसे कैसे प्राप्त करें मुझे कोई जानकारी नहीं है। लेकिन यही कारण है कि स्कैला जादुई रूप से समस्या से बचने लगता है।

प्रयोग, unapply कार्यों के जाहिरा तौर पर इस संस्करण है, हालांकि मैं थोड़ा लेकर संदेह में हूँ के बाद क्यों:

def unapply[A,B](value: BlackOrWhite[A,B]): Option[B] = value match { 
    case w: White[_,_] => Some(w.right) 
    case _ => None 
} 

अपने unapply के साथ कठिनाई किसी भी तरह संकलक आश्वस्त हो कि अगर एक White[A,B] फैली है कि BlackOrWhite[C,D] फिर BD जैसा ही है, जो स्पष्ट रूप से संकलक इस संस्करण में पता लगाने में सक्षम है लेकिन आपके नहीं में। यकीन नहीं है कि क्यों।

+2

असल में, 'अनुपयोगी' बनाया गया था ताकि उपयोगकर्ता कार्यक्षमता को दोहरा सके वह 'केस क्लास' पीआर ovided। कुछ अन्य स्थान हैं जहां चीजें काम करने के लिए आधिकारिक स्पष्टीकरण यह नहीं है कि संकलक वास्तव में ऐसा कैसे करता है। –

5

मैं आपको केस क्लास मैच और अनुपयोगी के बीच के अंतर पर उत्तर नहीं दे सकता। हालांकि उनकी पुस्तक (ओडर्स्की, चम्मच, वेनेर्स) में "प्रोग्रामिंग इन स्कैला" दूसरा अध्याय 26।6 "मामले वर्गों बनाम एक्सट्रैक्टर्स" वे लिखते हैं:

"वे (मामले वर्ग) आम तौर पर और अधिक कुशल पैटर्न के लिए नेतृत्व से मेल खाता है एक्सट्रैक्टर्स से , क्योंकि स्काला संकलक मामले वर्गों से अधिक पैटर्न बहुत एक्सट्रैक्टर्स से अधिक पैटर्न की तुलना में बेहतर अनुकूलन कर सकते हैं यह है क्योंकि केस कक्षाओं के तंत्र को ठीक किया गया है, जबकि एक अनुपयोगी या अनैच्छिक में एक विधि निकालने में सेक विधि लगभग कुछ भी कर सकती है। तीसरा, यदि आपके केस क्लास सीलबंद बेस क्लास से प्राप्त होते हैं, तो स्कैला कंपाइलर हमारे पैटर्न की जांच करेगा थकावट के लिए मेल खाता है और शिकायत करेगा कि संभावित मानों का कुछ संयोजनद्वारा कवर नहीं किया गया हैपैटर्न। ऐसा कोई exhaustiveness चेकों एक्सट्रैक्टर्स लिए उपलब्ध हैं। "

कौन सा मेरे लिए कहा गया है कि दो, और अधिक अलग एक से पहली नजर में उम्मीद करेंगे कर रहे हैं लेकिन क्या सटीक मतभेद हैं पर विशिष्ट किया जा रहा बिना।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^