2012-09-09 16 views
5

कोई बता सकता है कि निम्न कोड क्यों संकलित करता है?स्कैला पैटर्न मिलान और टाइप अनुमान

Option("foo") match { 
    case x: List[String] => println("A") 
    case _ => println("B") 
} 

यह मैं एक (उम्मीद) प्रकार विलोपन के बारे में चेतावनी देता है, लेकिन यह अभी भी संकलित करता है। मुझे उम्मीद है कि यह एक प्रकार की त्रुटि फेंकने की उम्मीद है, जैसे कि अगर मैं Option("foo") के बजाय "foo" पर मेल खाता हूं।

धन्यवाद!

+1

एक बग की तरह दिखता है। मैं इसकी रिपोर्ट करूंगा। – sschaef

उत्तर

2

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

scala> Option("foo") match { 
| case x: Tuple2[String,String] => println("TUPLE") 
| case x: List[String] => println("LIST") 
| case _ => println("OTHER") 
| } 
<console>:9: warning: non variable type-argument String in type pattern (String, String)  is unchecked since it is eliminated by erasure 
      case x: Tuple2[String,String] => println("TUPLE") 
       ^
<console>:10: warning: non variable type-argument String in type pattern List[String] is unchecked since it is eliminated by erasure 
      case x: List[String] => println("LIST") 
       ^

अद्यतन डब्ल्यू/आर/टी मामले वर्गों (नीचे टिप्पणी की वजह से): यहाँ एक उदाहरण एक और उत्पाद का उपयोग करता है है

scala> case class Foo(bar: Int) 
defined class Foo 

scala> val y: Product = Foo(123) 
y: Product = Foo(123) 
+0

ऐसा लगता है कि इसका 'उत्पाद' के साथ कुछ भी नहीं है। मैंने 'ऑप्शन ("foo") को अपने स्वयं के केस क्लास के साथ सिंगल पैरामीटर ले लिया और कोई त्रुटि नहीं है। – ghik

+2

एरर, केस क्लास स्वचालित रूप से उत्पाद का विस्तार करते हैं। प्रतिक्रिया संपादन देखें। – timothy

+1

ठीक है, लेकिन वास्तव में यह मामला वर्ग होना आवश्यक नहीं है। सामान्य गैर-अंतिम वर्ग भी त्रुटि का कारण नहीं है। – ghik

0

मैंने देखा है कि एक त्रुटि दिखाया जाता है के वर्ग आपके द्वारा मिलान किया जाने वाला मान अंतिम के रूप में घोषित किया जाता है (और हम जानते हैं कि String अंतिम है)। मुझे अभी भी पता नहीं है कि इसके बिना कोई त्रुटि क्यों है।

4

कोड टिप्पणी की है, तो चलो कि स्वाद के लिए एक क्षण ले जाने:

/** If we can absolutely rule out a match we can fail early. 
    * This is the case if the scrutinee has no unresolved type arguments 
    * and is a "final type", meaning final + invariant in all type parameters. 
    */ 

सूचना है कि कोई नहीं, अंतिम नहीं है, उदाहरण के लिए। मुझे सही पता है?

क्या तुमने कभी scalac -Ypatmat-डिबग कोशिश करते हैं, टिप्पणी यहाँ मदद कर सकता है:

https://github.com/scala/scala/pull/650

गम्यता लगभग पहुंच के भीतर है:

https://issues.scala-lang.org/browse/SI-6146

लेकिन मैं नहीं दिख रहा है किसी दिन के बारे में कोई वादा किया जा सकता है कि क्या चेतावनी दी जा सकती है। प्रदर्शन कारणों से? कोई यह भी कह सकता है, इसे किसी उदाहरण के बारे में चेतावनी क्यों दी जानी चाहिए [फू [_]]?

अभी के लिए, spec सेक्शन 8.2 - 8.4 प्रेरित करते हैं कि क्यों फू [ए] के खिलाफ मिलान दिलचस्प है (सीमाएं प्राप्त करने के कारण)। मुझे लगता है कि मैं फिर से पढ़ूंगा। कुछ कॉफी के बाद।

trait Foo[+A] 
final class Fuzz[+A] extends Foo[A] 
final object Fooz extends Foo[Nothing] 
object Futz extends Foo[Nothing] 

//error 
Fooz match { 
    case x: List[_] => println("A") 
    case _ => println("B") 
} 
//no error 
Futz match { ... } 
+0

अच्छा, लगा कि यह पैटर्न matcher के साथ कुछ quirk होगा लेकिन देर रात को देर से नहीं देख सका :-) – timothy

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