2015-03-13 9 views
9

तो मुझे '!' के बीच का अंतर पता है और '?', मैं सिर्फ पता है कि सबसे अच्छा तरीका है जब एक वैकल्पिक चरस्विफ्ट: वैकल्पिक चर के कॉल विधियां

var bar: Bar? = nil 

bar?.doSomething() // this will be valid, but wouldn't call doSomething 
bar!.doSomething() // Given error: EXC_BAD_INSTRUCTIONS (Obviously) 

लेकिन जब 'बार' शून्य नहीं है, इन दो विधि-कॉल कर रहे हैं दोनों वैध करने की एक विधि बुला उन्हें इस्तेमाल करने के लिए है चाहता हूँ ।

bar = Bar() 
bar?.doSomething() // Valid 
bar!.doSomething() // Valid 

तो मेरे सवाल है, क्या सबसे अच्छा तरीका है एक वैकल्पिक चर के तरीकों कॉल करने के लिए, है मैं व्यक्तिगत रूप से उपयोग करें:

if bar != nil { 
    bar!.doSomething() 
} 

या बार .doSomething() बिल्कुल वैसा ही करेंगे? ?

+0

अंगूठे का नियम: हर बार जब आप '!' लिखने से बच सकते हैं, ऐसा करें ('बूल' को अस्वीकार करने के अलावा)। इसमें उदा। मजबूर डाउनकास्ट 'के रूप में!'। '!' का मतलब है 'हे! ऐसा मत करो! यह खतरनाक है! मैंने आपको चेतावनी दी! ' –

+3

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

+2

@ माथियास बॉच '! 'का अर्थ है' मैं डेवलपर हूं और मैं कभी गलती नहीं करता! मेरा कार्यक्रम हमेशा ठीक तरह से चलता है! मैंने फैसला किया! ' मेरी राय में '!' का अर्थ है 'यह कभी भी शून्य नहीं होना चाहिए, अगर ऐसा नहीं होता है तो जारी रखें।' – Krzak

उत्तर

18

मुझे लगता है कि यह बुरा सलाह bar?.doSomething() से बचने के लिए और बदले में हमेशा if let bar = bar { ... } का उपयोग है को लागू करने की तरह है।

दो मुख्य कारण हैं:

पहले, bar?.doSomething() बस अधिक संक्षिप्त है। यदि आप सशर्त अभिव्यक्ति में केवल एक कथन के साथ if let लिख रहे हैं तो आपको शायद खुद से पूछना चाहिए कि क्या आप उस कोड को छोटे संस्करण के साथ एक पंक्ति पर नहीं रखना चाहते हैं।

हालांकि यह पूरी तरह से कानूनी कोड है ..

if let thing = thing { 
    thing.bar() 
} 

.. निम्नलिखित सिर्फ कानूनी रूप, बस जो बहुत छोटी ..

thing?.bar() 

दूसरा, और अधिक महत्वपूर्ण और के कोर करने के लिए है यह मुद्दा, वे वही नहीं हैं!if let एक संयुक्त परीक्षण, वैकल्पिक अनैपिंग और असाइनमेंट है जबकि bar? कुछ वैकल्पिक चेनिंग कहलाता है।

उत्तरार्द्ध कई मामलों में बहुत उपयोगी है जो आपको बहुत अच्छे कोड लिखने देता है। उदाहरण के लिए:

यह .. यह बदलने के लिए इस्तेमाल किया जा सकता ..

var imageGenerator: ImageGenerator? 

if let generator = imageGenerator { 
    myView.image = generator.generateImage() 
} else { 
    myView.image = nil 
} 

बस के साथ:

myView.image = self.imageGenerator?.generateImage() 

इसका कारण वैकल्पिक श्रृंखलन रिटर्न nil रूप में जल्द ही है क्योंकि यह चेन में nil से मुकाबला करता है। और चूंकि UIImageView में image: UIImage? है, यह उस शून्य मूल्य को लेता है। यहां तक ​​कि अगर यह एक ImageGenerator?

से आता है यह और भी अधिक उपयोगी जब शून्य वालों ऑपरेटर, ?? के साथ संयुक्त है।

अब आप इस कोड को बदल सकते हैं ..

var imageGenerator: ImageGenerator? 

if let generator = imageGenerator { 
    myView.image = generator.generateImage() 
} else { 
    myView.image = DefaultImage 
} 

.. में ..

myView.image = generator?.makeImageGenerator() ?? DefaultImage 

.. जो जिस तरह से अधिक संक्षिप्त है।

और क्योंकि वैकल्पिक श्रृंखलनचेन पर काम करता है .. आप भी कुछ ऐसा कर सकते हैं:

myView.image = delegate?.makeImageGenerator()?.generateImage() ?? DefaultImage 

कौन सा बन जाएगा ..

if let delegate = delegate { 
    if let generator = delegate.generatorForImage() { 
     if let image = generator.generateImage() { 
      myView.image = image 
     } else { 
      myView.image = DefaultImage 
     } 
    } else { 
     myView.image = DefaultImage 
    } 
} else { 
    myView.image = DefaultImage 
} 

.. आप का उपयोग नहीं किया है, तो वैकल्पिक चेनिंग और नील कोलेसिंग ऑपरेटर

(हाँ myView.image = DefaultImage अंत में ही सशर्त किया जा सकता है, लेकिन इसका मतलब है कि आप अभी भी अगर यह स्थापित किया गया था जांच करने के लिए अतिरिक्त कोड लागू करने के लिए की है। यह बहुत कम हो नहीं होते।)

वहाँ दो नए गुर :-)

4

जब आप ऐसा करेंगे

bar?.doSomething() 

यह वैकल्पिक श्रृंखलन कहा जाता है: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html

इसका मतलब है कि इस मामले में बार नहीं के बराबर है, यह DoSomething विधि करने के लिए जारी नहीं होगा, लेकिन एक शून्य लौट आते हैं। यदि आप उन मामलों को संभालना चाहते हैं जहां यह शून्य है, तो आपको यह जांचना चाहिए कि किसी ऑब्जेक्ट में शून्य है या नहीं। तुम भी इसे इस तरह, वैकल्पिक द्वारा बाध्यकारी कर सकता है:

if let unwrappedBar = bar { 
    unwrappedBar.doSomething() 
} else { 
    doSomeOtherThing() // In case it's nil 
} 

यह एक अस्थायी unwrappedBar बुलाया लगातार मानो जाने बयान के अंदर उपलब्ध मूल्य बनाता है (यदि आप इसे किसी अन्य नाम अगर आप चाहते हैं दे सकते हैं), अगर यह शून्य नहीं है https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID330

+0

ग्रेट, मुझे ** का उपयोग करना चाहिए यदि ** ** अधिक बार –

+0

यह वास्तव में बंद नहीं है। –

+0

@StefanArentz यह सच है, धन्यवाद।उम्मीद है कि यह अभी सही है। :) – alkku

2
bar?.doSomething() 

सबसे अच्छा तरीका है फोन करने के लिए है:

bar?.doSomething() ?? doSomeOtherThing() 

यहाँ वैकल्पिक मूल्यों का उपयोग करने के विभिन्न तरीकों के बारे में अधिक जानकारी है:

तुम भी वैकल्पिक श्रृंखलन और वालों ऑपरेटर के साथ एक छोटी सिंटैक्स का उपयोग कर सकते हैं एक वैकल्पिक चर की एक विधि। यह केवल कुछ कॉल करता है अगर बार शून्य न हो। आप कम से कम कोड लिखने और यह वास्तव में एक if let जांच

if let bar = bar { 
    bar.doSomething() 
} 
+1

मुझे लगता है कि 'अगर' हमेशा उपयोग करें 'की तुलना में यह बेहतर सलाह है। यह फ़ॉर्म किसी कारण से मौजूद है: यह संक्षेप में है। 'अगर चलो' अभी भी उपयोगी है लेकिन मेरी राय में एकल विधि कॉल के लिए नहीं है - यदि आप एक बार से अधिक बार 'बार' का उपयोग करते हैं, तो 'अगर चलो' शायद बेहतर है। –

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