2011-04-20 11 views
28

मैं हाल ही में देखा है कोड:इस तरह स्काला पकड़ने भ्रम

val maybeInt = catching(classOf[NFE]) opt arg.toInt 

इस opt क्या है? एक विकल्प? मूल्य निकालने के लिए getOrElse का उपयोग क्यों नहीं कर रहा है? उपर्युक्त कोड में, maybeInt कोई नहीं होगा यदि कोई संख्याफॉर्मेट अपवाद फेंक दिया जाता है?

+0

अरे, वह कोड परिचित है! :-) –

+0

मैं कल्पना करता हूं :) – Geo

उत्तर

34

catching ऐसा लगता है कि यह किसी प्रकार की विधि कॉल है, है ना? यह है, लेकिन यह वास्तव में कक्षा Catch का एक उदाहरण देता है; यह सीधे एक तर्क नहीं लेता है। इस वर्ग में दो विधियां हैं जो अपवादों से निपटने के लिए विशेष रूप से उपयोगी होती हैं (और कई अपवादों को पकड़ने के लिए कई और)।

scala> type NFE = NumberFormatException 
defined type alias NFE 

scala> import scala.util.control.Exception._ 
import scala.util.control.Exception._ 

scala> catching(classOf[NFE]).opt("fish".toInt) 
res0: Option[Int] = None 

scala> catching(classOf[NFE]).opt("42".toInt) 
res1: Option[Int] = Some(42) 
: आप यह कुछ है कि एक अपवाद फेंक कर सकते हैं और None देते हैं, और यह Some(result) वापस आ जाएगी, तो सब कुछ ठीक चला गया, अगर लक्षित अपवाद पकड़ा गया था - पहली

def opt [U >: T] (body: ⇒ U) : Option[U] 

जो यहां इस्तेमाल किया जा रहा है

इसके बाद आप map या filter या getOrElse या विकल्पों के साथ निपटने के लिए जो कुछ भी उपयोग करते हैं, उसके साथ आप इसका सामना कर सकते हैं।

अन्य उपयोगी विधि either, जो Left(exception) का एक उदाहरण देता है, तो एक अपवाद फेंक दिया गया था, और एक Right(result) अगर यह नहीं था:

scala> catching(classOf[NFE]).either("fish".toInt) 
res2: Either[Throwable,Int] = Left(java.lang.NumberFormatException: For input string: "fish") 

scala> catching(classOf[NFE]).either("42".toInt) 
res3: Either[Throwable,Int] = Right(42) 

फिर आप fold का उपयोग करें या एक विकल्प या जो कुछ भी करने के लिए मैप कर सकते हैं अन्यथा आप eithers के साथ करना पसंद है।

ध्यान दें कि आप एक ही पकड़ने को परिभाषित करने और इसे कई बार उपयोग कर सकते हैं (ताकि आप, पकड़ने वाला वस्तु हर बार जब आप बनाने के लिए उदाहरण के लिए की जरूरत नहीं है, पार्स एक पूर्णांक):

scala> val catcher = catching(classOf[NFE]) 
catcher: util.control.Exception.Catch[Nothing] = Catch(java.lang.NumberFormatException) 

scala> catcher.opt("42".toInt) 
res4: Option[Int] = Some(42) 

scala> catcher.opt("fish".toInt) 
res5: Option[Int] = None 

संपादित करें: जैसा कि डैनियल टिप्पणियों में बताता है, यह अभी भी एक अस्थायी Catch[Option] बनाता है; विधि हस्ताक्षर दिए जाने के बाद, इसे किसी भी अतिरिक्त ऑब्जेक्ट्स के बिना जाल अपवादों और विकल्पों को उत्पन्न करने का कोई आसान तरीका नहीं है। यह मुझे याद दिलाता है कारण है कि मैं वास्तव में ऐसा करने के लिए अपने खुद के तरीकों लिखें:

def optNFE[T](t: => T) = try { Some(t) } catch {case nfe: NFE => None} 
optNFE("fish".toInt) // gives None 
optNFE("42".toInt) // gives Some(42) 
+0

धन्यवाद रेक्स! मैं इसे अच्छे उपयोग के लिए रखूंगा :) – Geo

+0

यह वास्तव में आसान है। कोई विचार नहीं था। अद्यतित करने के लिए धन्यवाद। – overthink

+6

असल में, 'पकड़ने' 'कैच [एनएफई] 'वापस नहीं करेगा, लेकिन' पकड़ो [कुछ नहीं]'। प्रकार पैरामीटर या 'कैच' इंगित करता है कि अपवाद के मामले में यह क्या हो सकता है। उदाहरण के लिए, 'withApply'' फ़ंक्शन 'थ्रोबल => यू' लेता है, और' कैच [यू] 'देता है। विधि 'ऑप्ट' पहले 'कैच [विकल्प [एक्स]] प्राप्त करने के लिए 'toOption' का उपयोग करेगी, जो अपवाद फेंकने पर' कोई नहीं 'लौटाता है, और फिर उस कैचर को' कुछ (बॉडी) 'पास करता है। –

0

मैं एक और अधिक सरल पैटर्न का उपयोग जब वहाँ केवल एक ही कमी है:

try{ 
     return args.split(" ").exists(line.startsWith _) 
}catch { 
    case _ =>{//generic exception 
     logger.error("Error with line ${line} for ${ex.message}") 
     throw _ 
    }  
} 

मैं निश्चित रूप से अभी तक एक स्काला समर्थक नहीं हूँ , और मुझे लगता है कि आप छोटी सामग्री