2010-04-28 16 views
9

में सभी अपवादों मैं फ़ाइल test.scala में निम्नलिखित डमी स्काला कोड है:पकड़ने स्काला 2.8 RC1

class Transaction { 
    def begin() {} 
    def commit() {} 
    def rollback() {} 
} 

object Test extends Application { 
    def doSomething() {} 

    val t = new Transaction() 
    t.begin() 
    try { 
    doSomething() 
    t.commit() 
    } catch { 
    case _ => t.rollback() 
    } 
} 

यदि मैं यह स्काला 2.8 RC1 पर scalac -Xstrict-warnings test.scala साथ संकलन मैं निम्न चेतावनी मिल जाएगा:

test.scala:16: warning: catch clause swallows everything: not advised. 
    case _ => t.rollback() 
    ^
one warning found 

तो, अगर पकड़ें- सभी अभिव्यक्तियों की सलाह नहीं दी जाती है, तो मुझे इसके बजाय इस तरह के पैटर्न को कैसे लागू करना चाहिए? और इसके अलावा ऐसे अभिव्यक्तियों को किसी भी तरह क्यों सलाह नहीं दी जाती है?

उत्तर

9

चेतावनी मौजूद है क्योंकि आप शायद सब कुछ को पकड़ने के लिए नहीं करना चाहती। उदाहरण के लिए, java.lang.Error में कुछ भी पकड़ने की कोशिश करने के लिए आम तौर पर यह अव्यवस्थित है क्योंकि अक्सर ऐसी चीजों से पुनर्प्राप्त करना मुश्किल होता है। (संभावनाएं अच्छी हैं कि आपको अपने कैच ब्लॉक से दूसरे अपवाद के साथ फेंक दिया जाएगा।)

इसके अलावा, क्योंकि आप उपयोगी रूप से सब कुछ नहीं पकड़ सकते हैं, यह परमाणु/असफल लेनदेन को लागू करने का एक सुरक्षित तरीका नहीं है। जब एक नया t में पढ़ने यकीन है कि यह एक समझदार स्थिति में नहीं है बनाने के लिए आप अतिरिक्त परीक्षण के साथ की तरह

try { 
    t.commit() 
} finally { 
    if (!t.checkCommitted()) { 
    t.rollback() 
    if (!t.checkRolledback()) throw new FUBARed(t) 
    } 
} 

कुछ के साथ बेहतर कर रहे हैं।

+0

ठीक है। यह लेनदेन के लिए काम करता है। लेकिन क्या होगा अगर मैं पूरी तरह से एक अपवाद एक विधि सिर्फ इसलिए कि यह इस बिंदु पर कोई फर्क नहीं पड़ता द्वारा फेंका अनदेखा करना चाहते। –

+5

आप {केस _: अपवाद =>} 'पकड़ सकते हैं। 'त्रुटि' 'थ्रोबल 'है लेकिन' अपवाद 'नहीं - आमतौर पर जाने के लिए बेहतर है। यदि आपका वास्तव में मतलब है, "मुझे कोई परवाह नहीं है कि मैं कोशिश करता हूं और इसे पकड़ने में असफल रहता हूं, मैं कम से कम इसे अपना सर्वश्रेष्ठ शॉट देना चाहता हूं", तो आप (सख्त) चेतावनी संदेश के साथ रह सकते हैं। यही कारण है कि यह एक चेतावनी है, एक त्रुटि नहीं। –

+0

हाँ, यह काम करता है। धन्यवाद! आप सही हैं, 'त्रुटि' को पकड़ना वास्तव में मैं नहीं चाहता हूं :-) –

2

मेरे पास इसका परीक्षण करने के लिए एक कंपाइलर नहीं है, लेकिन क्या आपको लेनदेन को वापस लाने के बाद अपवाद को फिर से फेंकना नहीं चाहिए? यानी यह

val t = new Transaction() 
t.begin() 
try { 
    doSomething() 
    t.commit() 
} catch { 
    case e => t.rollback(); throw e 
} 

होना चाहिए आप सभी अपवादों को पकड़ने रहे हैं, तो आप the documentation for ControlThrowable पर ध्यान देना चाहिए। संभवतः आप अपने लेनदेन को असामान्य समाप्ति पर वापस रोल करना चाहते हैं, लेकिन यह नहीं चाहते कि वह गैर-स्थानीय रिटर्न या util.control.Breaks.break के लिए वापस रोल करें। यदि हां, तो आप निम्नलिखित की तरह कुछ करने के लिए चाहते हो सकता है:

val t = new Transaction() 
t.begin() 
try { 
    doSomething() 
    t.commit() 
} catch { 
    case ce : ControlThrowable => throw ce // propagate 
    case e => t.rollback(); throw e  // roll-back and propagate 
} 
+0

धन्यवाद, लेकिन यह कोड अभी भी उपरोक्त चेतावनी की ओर जाता है। –

+0

क्या मामला ई => फेंक दिया गया है 'कॉलस्टैक साफ़ करें? –

1

सबसे पहले, ध्यान दें कि यह एक चेतावनी है, कोई त्रुटि नहीं। और फिर भी, केवल एक चेतावनी -Xstrict-warings विकल्प के साथ उठाया गया चेतावनी। दूसरे शब्दों में, इसका मतलब है कि शायद आप एक तर्क गलती कर रहे हैं, लेकिन यह निर्णय लेने के लिए आप पर निर्भर है।

दूसरों के रूप में देखा है, ज्यादातर मामलों में यह नहीं सार्थक सब अपवाद को पकड़ने के लिए है और आप कुछ इस तरह करना चाहिए:

t.begin() 
try { 
    doSomething() 
    t.commit() 
} catch { 
    case e: DuplicatedKeyError => ... 
    case e: BrokenConnectionError => ... 
    case e: DumbInputDetectedError => ... 
} 

अर्थात संभाल meaningfuly सभी ज्ञात त्रुटि प्रकारों।

लेकिन अगर आप सकारात्मक है कि आप की अनदेखी (या उसी तरह संभाल) सभी संभव अपवाद करना चाहते हैं, तो बस चेतावनी को अनदेखा।

try { 
    android.util.Log.i (TAG, "Feature " + Text) 
    statements 
    } 
    catch { 
    case exception: Throwable => 
     val Message = "Feature " + Text + "failed" 
     android.util.Log.e (TAG, Message, exception) 
     fail (Message) 
    } // try 

ऊपर अगर उदाहरण इकाई परीक्षण का एक टुकड़ा से:

1

आप सभी को पकड़ने की अपनी मंशा राज्य के लिए Throwable को पकड़ने के लिए की है। चेतावनी के अनुसार: सामान्य कोड