2015-06-09 5 views
13

स्विफ्ट 1.2 में मैं इस है:स्विफ्ट 2 अगर साथ जाने do-कोशिश-पकड़

if let filePath = NSBundle.mainBundle().pathForResource("some", ofType: "txt"), 
     data = String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding) { 
    for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) { 
     // Do something 
    }  
} else { 
    println("some.txt is missing") 
} 

स्विफ्ट 2 में, मैं अब यह कर सकते हैं, क्योंकि दोनों pathForResource और contentsOfFile फेंक कर सकते हैं, साथ ही लौटने optionals। मैं इसे ठीक कर सकते हैं, लेकिन अब यह उल्लेखनीय वर्बोज़ लगता है:

do { 
    if let filePath = try NSBundle.... { 
     do { 
      if let data = try String.... { 
       for line in data..... { 
        // Do something 
       } 
      } else { 
       print("Nil data") 
      } 
     } catch { 
      print("contentsOfFile threw") 
     } 
    } else { 
     print("Nil pathForResource") 
    } 
} catch { 
    print("pathForResource threw") 
}  

मैं उम्मीद मैं कुछ छूट गया है - किसी भी मदद की सराहना की।

+1

बस मुख्य नोट देखा। मैंने सोचा कि आपके पास 'do' ब्लॉक में एकाधिक 'try' कथन हो सकते हैं। क्या यह संभव नहीं है? – dreamlab

+0

मैंने अभी तक मुख्य नोट नहीं देखा है लेकिन ऐसा लगता है जैसे स्विफ्ट का फीचर सेट लगभग तेजी से बढ़ रहा है। – sbooth

+0

हर बार जब आप 'try' का उपयोग करते हैं तो आपको' पकड़ 'नहीं होना चाहिए। असल में, अधिकांश समय आपको शायद अपवाद नहीं लेना चाहिए, और इसके बजाय उन्हें ऊपर की तरफ प्रचार करना चाहिए। Http://exceptionsafecode.com/ देखें (यह सी ++ के बारे में बात करता है, लेकिन स्विफ्ट के अपवाद मॉडल को देखने के बाद मुझे लगता है कि सिद्धांत स्विफ्ट पर भी लागू होते हैं।) – bames53

उत्तर

13

if-let के बजाय गार्ड सिंटैक्स का उपयोग करें।

यहाँ एक नमूना है:

do { 

    guard let filePath = try NSBundle .... else { 
     // if there is exception or there is no value 
     throw SomeError 
    } 
    guard let data = try String .... else { 
    } 

} catch { 

} 

अगर-जाने और गार्ड unwrapped मूल्य का दायरा है के बीच का अंतर। यदि आप if-let filePath मान का उपयोग करते हैं तो केवल if-let ब्लॉक के अंदर उपलब्ध है। आप गार्ड FilePath का उपयोग करते हैं मूल्य कि गार्ड में कहा जाता है गुंजाइश के लिए उपलब्ध है।

यहाँ तेजी से पुस्तक

एक गार्ड बयान, एक अगर बयान की तरह के प्रासंगिक अनुभागों है, बूलियन पर आधार पर बयान निष्पादित करता है एक अभिव्यक्ति का मूल्य। आप पर एक गार्ड स्टेटमेंट का उपयोग करते हैं, ताकि गार्ड स्टेटमेंट निष्पादित होने के बाद कोड के लिए एक शर्त सही होनी चाहिए। यदि एक कथन के विपरीत, एक गार्ड कथन में हमेशा एक और क्लॉज होता है- अन्य 'क्लॉज के अंदर कोड निष्पादित किया जाता है यदि स्थिति सत्य नहीं है।

+0

अभी तक इसे आजमा देने में सक्षम नहीं है, लेकिन यह समझ में आता है। मैं दस्तावेज़ों में कुछ भी नहीं देख सका, जिसमें कहा गया था कि एक ही काम में कई 'कोशिश' करना ठीक था, लेकिन वह ऐसा करेगा! धन्यवाद! – Grimxn

8

पास के रूप में मैं बता सकता हूँ, ऊपर में केवल अपने स्ट्रिंग प्रारंभकर्ता वास्तव में एक त्रुटि फेंकता है (हालांकि pathForResource() कुछ बिंदु पर एक त्रुटि फेंक करने के लिए एक वैकल्पिक मूल्य लौटने से बदल सकते हैं)। इसलिए, नीचे की नकल करना चाहिए कि क्या आप पहले किया था:

if let filePath = NSBundle.mainBundle().pathForResource("some", ofType: "txt") { 
    do { 
     let data = try String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding) 
     for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) { 
       // Do something 
     } 
    } catch { 
     print("Couldn't load the file somehow") 
    } 
} else { 
    print("some.txt is missing") 
} 

आपका स्ट्रिंग वैकल्पिक नहीं रह गया है, इसलिए वहाँ एक if let के लिए कोई आवश्यकता नहीं है। , अगर pathForResource() एक त्रुटि फेंक करने के लिए एक वैकल्पिक लौटने से बदल गया है, बस

guard let filePath = NSBundle.mainBundle().pathForResource("some", ofType: "txt") else { 
    print("some.txt is missing") 
} 
do { 
    let data = try String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding) 
    for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) { 
     // Do something 
    } 
} catch { 
    print("Couldn't load the file somehow") 
} 

अब आप कर सकते हैं:

मुस्तफा बताते हैं के रूप में, एक guard बयान सफलता के मामले में खरोज का एक स्तर को दूर करने के लिए इस्तेमाल किया जा सकता है फेंकने के लिए एक त्रुटि उस बिंदु पर बाहर निकाल देगा, अतीत कि कुछ भी के निष्पादन को रोकने

do { 
    let filePath = try NSBundle.mainBundle().pathForResource("some", ofType: "txt") 
    let data = try String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding) 
    for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) { 
     // Do something 
    } 
} catch { 
    print("some.txt is missing") 
} 

पहले बयान: इन अनुक्रम में बयान की कोशिश का उपयोग करें। एक सिंगल कैच स्टेटमेंट फेटेबल ऑपरेशंस की श्रृंखला से कुछ भी लेने के लिए पर्याप्त है, जिससे उन्हें चेन करना आसान हो जाता है।

+0

अंतिम उदाहरण में, त्रुटि को अधिक सटीक रूप से वर्णित करने के लिए कैच क्लॉज को कैसे अपडेट किया जाएगा, क्योंकि हम अब यह नहीं कह सकते कि "some.txt गुम है" (शायद यह सामग्री थीफाइल: एन्कोडिंग: 'वह फेंक दिया गया था)? या क्या हम कुछ सामान्य "कुछ गलत हो गए" संदेश तक सीमित हैं? –

+1

@ बेनपाकार्ड - चूंकि दोनों त्रुटि-फेंकने वाली रेखाएं एक एनएसईआरआरआर को वापस लाती हैं, इसलिए कैच स्टेटमेंट में आने वाले अंतर्निहित 'त्रुटि' पैरामीटर को सुरक्षित रूप से एनएसईआरआरआर में डाला जा सकता है और जांच की जा सकती है। आप या तो उस NSError (शायद सबसे वर्णनात्मक नहीं) का उपयोग कर सीधे उपयोगकर्ता को एक त्रुटि प्रस्तुत कर सकते हैं, या आप त्रुटि कोड और डोमेन को उसमें से खींच सकते हैं और उस सटीक त्रुटि के आधार पर अपनी त्रुटि रिपोर्ट बना सकते हैं। आप किसी भी फिक्स्ड ऑपरेशंस से सभी त्रुटि मामलों को संभाल सकते हैं। –

+0

मैं देखता हूं - और संभवतः अगर कोई अन्य फेंकने वाला फ़ंक्शन जोड़ा गया था जो किसी एनएसईआरआर के बजाय कुछ एनएसईआरर टाइप टाइप करता था, जिसे किसी अन्य कैच स्टेटमेंट (या प्रत्येक प्रकार के प्रति एक) में संभाला जा सकता है। धन्यवाद। –

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