2015-01-05 8 views
7

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

एक उदाहरण के रूप:

में
def f(): String = null 

for { 
    a <- Option("hello") 
    b = f() 
} yield (a, b) 

परिणाम की उम्मीद:

//> res0: Option[(String, String)] = Some((hello,null)) 

लेकिन, अगर मैं तो मैं b

def f(): String = null 

for { 
    a <- Option("hello") 
    b: String = f() 
} yield (a, b) 

के प्रकार के लिए एक प्रकार का टिप्पणी जोड़ने रनटाइम अपवाद:

//> scala.MatchError: (hello,null) (of class scala.Tuple2) 

ऐसा क्यों होता है? वैसे भी पहले उदाहरण में टाइप b नहीं है? दूसरे उदाहरण में स्पष्ट प्रकार एनोटेशन क्या बदलता है?

(ध्यान दें, उदाहरण स्काला 2.11.4 में चला गया)

+0

के रूप में आप 'reify' repl में उपयोग करते हुए देख सकते हैं दूसरा उदाहरण, एक मैच के लिए संकलित:' आयात scala.reflect.runtime.universe ._; {{{}}} के लिए {पुनः प्राप्त करें। मैं आपको क्यों नहीं बता सकता। एआईयूआई 'नल' मेल नहीं खाता है क्योंकि रनटाइम प्रकार (या मूल्य) पर मेल खाने वाले काम, भले ही 'बी' में 'स्ट्रिंग' का संकलन-समय प्रकार हो; यह कुछ अर्थ में टाइप सिस्टम में एक छेद है, और स्कैला कोड आम तौर पर नल का उपयोग करने से बचना चाहिए। – lmm

+0

मैं नल का कोई प्रशंसक नहीं हूं, मेरा विश्वास करो! वास्तविक कोड में जहां मैंने इस पर ठोकर खाई थी, मैं 'कुछ विरासत जावा कोड के साथ एकीकृत करने के लिए प्रयास करें' का उपयोग कर रहा था। हालांकि, शून्य मेरे लिए आकस्मिक प्रतीत होता है: पहलू मुझे विचित्र लगता है (डरावना?) यह है कि अधिक प्रकार के विशिष्टता परिणामों को एक (अनजान) रनटाइम अपवाद में जोड़ना। –

+0

यह भाषा की अजीबता है जो एक पैटर्न के लिए ''' '' 'उपज' परिणामों में प्रकार डालती है; यह कोई समस्या नहीं है जो अभिव्यक्तियों पर "सामान्य" प्रकारों के साथ घटित होगी। मैं बस इतना कह सकता हूं कि यह दुर्भाग्यपूर्ण है, लेकिन शायद इस चरण में बदला नहीं जा सकता है; मैं इस कारण से उपज/उपज के बाईं ओर एक प्रकार देने से बचता हूं:/ – lmm

उत्तर

7

null कुछ भी का एक उदाहरण नहीं है:

scala> (null: String) match { case _: String => } 
scala.MatchError: null 
    ... 33 elided 

scala> val s: String = null 
s: String = null 

scala> s.isInstanceOf[String] 
res1: Boolean = false 

http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#type-patterns

प्रकार पैटर्न में गैर-शून्य निर्दिष्ट करता है।

अनुवाद दिखाने के लिए एक चाल टिप्पणी करने के लिए शो है:

scala> for { 
    | a <- Option("hello") 
    | b: String = f() 
    | } yield (a, b) // show 
object $read extends scala.AnyRef { 
    def <init>() = { 
    super.<init>; 
    () 
    }; 
    object $iw extends scala.AnyRef { 
    def <init>() = { 
     super.<init>; 
    () 
    }; 
    import $line4.$read.$iw.$iw.f; 
    object $iw extends scala.AnyRef { 
     def <init>() = { 
     super.<init>; 
     () 
     }; 
     val res1 = Option("hello").map(((a) => { 
     val b: String = f; 
     scala.Tuple2(a, b) 
     })).map(((x$1) => x$1: @scala.unchecked match { 
     case scala.Tuple2((a @ _), (b @ (_: String))) => scala.Tuple2(a, b) 
     })) 
    } 
    } 
} 
scala.MatchError: (hello,null) (of class scala.Tuple2) 
    at $anonfun$2.apply(<console>:10) 
    at $anonfun$2.apply(<console>:10) 
    at scala.Option.map(Option.scala:145) 
    ... 39 elided 
+0

यह दिखाता है कि क्या गलत हो रहा है, लेकिन यह तर्कसंगत रूप से एक बग है क्योंकि उस अंतिम मानचित्र पर पैटर्न मिलान का कोई कारण नहीं है क्योंकि _bu construction_ के पास पहले से सही प्रकार है ('val b: String = f' पर)। (यह तर्कसंगत रूप से एक बग है कि पहचान फ़ंक्शन को अनुकूलित नहीं किया गया है, लेकिन हम एक और जटिल मामले की कल्पना कर सकते हैं।) –

+0

@RexKerr हाँ, तर्कसंगत रूप से। यह एक मजबूत तर्क है अगर यह पुराने 'वैल बी: स्ट्रिंग = एफ() 'सिंटैक्स, शायद मॉड्यूलो एसआई -9 00 का उपयोग करता है जहां जनरेटर पर प्रकार पॅट फ़िल्टर का मतलब है। लेकिन आप सामान्य मैच को अनुकूलित नहीं करेंगे। शायद हमें 'वैल i = 42: Int' लिखना शुरू करना चाहिए। फिर 'वैल एस: स्ट्रिंग = नल: स्ट्रिंग 'विफल हो सकता है जैसे कि' टुपले 1 'में लपेटा गया है। –

+0

क्या भाषा का नमूना यह निर्धारित करता है कि समझ में टाइप एनोटेशन की डी-शर्करा पैटर्न पैटर्न के रूप में लागू की जाएगी? –

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