ios - स्विफ्ट में "अनचाहे मूल्य" क्या है?




swift ios8 (3)

'?' वैकल्पिक चेनिंग अभिव्यक्ति का मतलब है

'!' का अर्थ बल-मूल्य है

मैं इस ट्यूटोरियल का पालन ​​करके आईओएस 8 / ओएसएक्स 10.10 के लिए स्विफ्ट सीख रहा हूं, और इस अनुच्छेद ( ऑब्जेक्ट्स और क्लास के तहत) में " अनचाहे मूल्य " शब्द का प्रयोग कई बार किया जाता है:

वैकल्पिक मूल्यों के साथ काम करते समय, आप लिख सकते हैं? विधियों, गुणों, और सबस्क्रिप्टिंग जैसे संचालन से पहले। यदि इससे पहले मूल्य? शून्य है, सब कुछ के बाद? अनदेखा किया जाता है और पूरी अभिव्यक्ति का मूल्य शून्य है। अन्यथा, वैकल्पिक मूल्य अनचाहे है , और सब कुछ के बाद? अनचाहे मूल्य पर कार्य करता है। दोनों मामलों में, संपूर्ण अभिव्यक्ति का मूल्य एक वैकल्पिक मान है।

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square") 
let sideLength = optionalSquare?.sideLength

मुझे यह नहीं मिला, और भाग्य के बिना वेब पर खोज की।

इसका क्या मतलब है?

संपादित करें

सेज़री के जवाब से, मूल कोड के आउटपुट और अंतिम समाधान (खेल के मैदान पर परीक्षण) के बीच थोड़ा सा अंतर है:

मूल कोड

Cezary का समाधान

सुपरक्लास 'गुण दूसरे मामले में आउटपुट में दिखाए जाते हैं, जबकि पहले मामले में एक खाली वस्तु होती है।

क्या परिणाम दोनों मामलों में समान नहीं होना चाहिए?

संबंधित प्रश्नोत्तर: स्विफ्ट में वैकल्पिक मूल्य क्या है?


मौजूदा सही उत्तर बहुत अच्छा है, लेकिन मैंने पाया कि मेरे लिए यह पूरी तरह से समझने के लिए, मुझे एक अच्छा सादृश्य चाहिए, क्योंकि यह एक बहुत ही अमूर्त और अजीब अवधारणा है।

तो, मुझे सही जवाब के अलावा एक अलग परिप्रेक्ष्य देकर उन साथी "दाएं दिमागी" (दृश्य सोच) डेवलपर्स की मदद करने दें। यहां एक अच्छा सादृश्य है जिसने मुझे बहुत मदद की।

जन्मदिन वर्तमान लपेटना एनालॉजी

विकल्प के बारे में सोचें जैसे कि जन्मदिन उपहार प्रस्तुत करना जो कठोर, कठोर, रंगीन लपेटन में आते हैं।

आप नहीं जानते कि रैपिंग के अंदर कुछ भी है जब तक आप वर्तमान को खोल नहीं लेते - शायद अंदर कुछ भी नहीं है! अगर अंदर कुछ है, तो यह एक और उपस्थिति हो सकता है, जिसे भी लपेटा जाता है, और इसमें कुछ भी नहीं हो सकता है । अंततः यह पता लगाने के लिए कि आप लपेटने के अलावा कुछ भी नहीं था, आप 100 नेस्टेड उपहारों को भी खोल सकते हैं।

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

बॉक्स में क्या है?! समानता

वैरिएबल को खोलने के बाद भी, आप एसई 7EN ( चेतावनी : खराब करने वाले और बहुत आर रेटेड गलत भाषा और हिंसा) के आखिरी दृश्य में ब्रैड पिट की तरह हैं, क्योंकि वर्तमान में आप को खोलने के बाद भी, आप निम्न स्थितियों में हैं: अब आपके पास nil , या एक बॉक्स जिसमें कुछ है (लेकिन आप नहीं जानते कि क्या)।

आप कुछ प्रकार के बारे में जान सकते हैं। उदाहरण के लिए, यदि आपने वैरिएबल को प्रकार के रूप में घोषित किया है, [Int:Any?] , तो आपको पता चलेगा कि आपके पास पूर्ण (संभावित रूप से खाली) शब्दकोश है जो पूर्णांक सदस्यता के साथ है जो किसी भी पुराने प्रकार की लिपटे सामग्री उत्पन्न करता है।

यही कारण है कि स्विफ्ट में संग्रह प्रकार (शब्दकोश और Arrays) से निपटने से बालों का प्रकार मिल सकता है।

इसका स्पष्ट उदाहरण:

typealias presentType = [Int:Any?]

func wrap(i:Int, gift:Any?) -> presentType? {
    if(i != 0) {
        let box : presentType = [i:wrap(i-1,gift:gift)]
        return box
    }
    else {
        let box = [i:gift]
        return box
    }
}

func getGift() -> String? {
    return "foobar"
}

let f00 = wrap(10,gift:getGift())

//Now we have to unwrap f00, unwrap its entry, then force cast it into the type we hope it is, and then repeat this in nested fashion until we get to the final value.

var b4r = (((((((((((f00![10]! as! [Int:Any?])[9]! as! [Int:Any?])[8]! as! [Int:Any?])[7]! as! [Int:Any?])[6]! as! [Int:Any?])[5]! as! [Int:Any?])[4]! as! [Int:Any?])[3]! as! [Int:Any?])[2]! as! [Int:Any?])[1]! as! [Int:Any?])[0])

//Now we have to DOUBLE UNWRAP the final value (because, remember, getGift returns an optional) AND force cast it to the type we hope it is

let asdf : String = b4r!! as! String

print(asdf)

स्विफ्ट प्रकार सुरक्षा पर एक उच्च प्रीमियम रखता है। पूरी स्विफ्ट भाषा को दिमाग में सुरक्षा के साथ बनाया गया था। यह स्विफ्ट के एक हॉलमार्क में से एक है और एक जिसे आपको खुली बाहों के साथ स्वागत करना चाहिए। यह स्वच्छ, पठनीय कोड के विकास में सहायता करेगा और आपके आवेदन को दुर्घटनाग्रस्त होने में मदद करेगा।

स्विफ्ट में सभी विकल्प हैं जिनके साथ सीमांकन किया गया है ? प्रतीक। सेट करके ? उस प्रकार के नाम के बाद जिसमें आप वैकल्पिक के रूप में घोषित कर रहे हैं, आप अनिवार्य रूप से इसे इस प्रकार कास्टिंग नहीं कर रहे हैं जैसा कि पहले है ? , लेकिन वैकल्पिक प्रकार के रूप में।

नोट: एक चर या प्रकार Int के समान नहीं है Int? । वे दो अलग-अलग प्रकार हैं जिन्हें एक-दूसरे पर संचालित नहीं किया जा सकता है।

वैकल्पिक का उपयोग करना

var myString: String?

myString = "foobar"

इसका मतलब यह नहीं है कि आप एक प्रकार के String साथ काम कर रहे हैं। इसका मतलब है कि आप एक प्रकार के String? साथ काम कर रहे हैं String? (स्ट्रिंग वैकल्पिक, या वैकल्पिक स्ट्रिंग)। वास्तव में, जब भी आप प्रयास करते हैं

print(myString)

रनटाइम पर, डीबग कंसोल Optional("foobar") प्रिंट करेगा। " Optional() " भाग इंगित करता है कि इस चर को रनटाइम पर कोई मान हो सकता है या नहीं हो सकता है, लेकिन वर्तमान में स्ट्रिंग "foobar" होने के साथ ऐसा होता है। यह " Optional() " संकेत तब तक रहेगा जब तक कि आप वैकल्पिक मूल्य को "अनचाहे" कहलाते हैं।

वैकल्पिक तरीकों को अनवरोधित करना कि अब आप उस प्रकार को गैर-वैकल्पिक के रूप में कास्टिंग कर रहे हैं। यह एक नया प्रकार उत्पन्न करेगा और उस मान को असाइन करेगा जो उस वैकल्पिक के भीतर नए गैर-वैकल्पिक प्रकार के लिए रहता है। इस तरह आप उस चर पर संचालन कर सकते हैं क्योंकि संकलक द्वारा ठोस मूल्य रखने की गारंटी दी गई है।

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

नोट: आप अपने सशर्त रूप से अनचाहे निरंतर समान नाम को वैकल्पिक चर के रूप में दे सकते हैं जिसे आप अनचाहे कर रहे हैं।

if let myString = myString {
    print(myString)
    // will print "foobar"
}

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

if let myString = myString {
    print(myString)
    // will print "foobar"
}
else {
    print("No value")
}

जबरन अनवरत करना जो नियोजित है उसे नियोजित करके किया जाता है ! ("बैंग") ऑपरेटर। यह कम सुरक्षित है लेकिन फिर भी आपके कोड को संकलित करने की अनुमति देता है। हालांकि जब भी आप बैंग ऑपरेटर का उपयोग करते हैं तो आपको 1000% निश्चित होना चाहिए कि आपके चर में वास्तव में जबरन अवांछित होने से पहले ठोस मूल्य होता है।

var myString: String?

myString = "foobar"

print(myString!)

यह उपरोक्त मान्य स्विफ्ट कोड है। यह myString के मान को प्रिंट करता है जिसे "foobar" के रूप में सेट किया गया था। उपयोगकर्ता कंसोल में मुद्रित foobar देखेंगे और यह इसके बारे में है। लेकिन आइए मान लें कि मान कभी सेट नहीं किया गया था:

var myString: String?

print(myString!) 

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

Unwrapping w / प्रकार कास्टिंग । जैसा कि हमने पहले कहा था कि जब आप वैकल्पिक रूप से unwrapping होते हैं तो आप वास्तव में एक गैर-वैकल्पिक प्रकार के लिए कास्टिंग कर रहे हैं, आप गैर-वैकल्पिक को एक अलग प्रकार में भी डाल सकते हैं। उदाहरण के लिए:

var something: Any?

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

नोट: ऑपरेटर के as आप स्विफ्ट में कैसे कास्ट टाइप करते हैं।

// Conditionally
if let thing = something as? Int {
    print(thing) // 0
}

// Optionally
let thing = something as? Int
print(thing) // Optional(0)

// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised

कीवर्ड के as में दोनों के बीच अंतर पर ध्यान दें। इससे पहले कि जब हमने जबरन एक वैकल्पिक विकल्प को तोड़ दिया तो हमने इसका इस्तेमाल किया ! ऐसा करने के लिए बैंग ऑपरेटर। यहां आप एक ही काम करेंगे लेकिन केवल एक गैर-वैकल्पिक के रूप में कास्टिंग करने के बजाय आप इसे Int रूप में भी कास्टिंग कर रहे हैं। और यह Int रूप में डाउनकास्ट करने में सक्षम होना चाहिए, अन्यथा, बैंग ऑपरेटर का उपयोग करने की तरह, जब मूल्य nil आपका एप्लिकेशन क्रैश हो जाएगा।

और इन चरों का उपयोग किसी प्रकार या गणितीय ऑपरेशन में करने के लिए करने के लिए उन्हें ऐसा करने के लिए अनचाहे होना चाहिए।

उदाहरण के लिए, स्विफ्ट में एक ही प्रकार के वैध संख्या डेटा प्रकारों को एक-दूसरे पर संचालित किया जा सकता है। जब आप एक प्रकार के साथ के as! कास्ट as! आप उस चर के डाउनकास्ट को मजबूर कर रहे हैं जैसे कि आप निश्चित हैं कि यह उस प्रकार का है, इसलिए अपने एप्लिकेशन को क्रैश करने और क्रैश करने के लिए सुरक्षित नहीं है। यह तब तक ठीक है जब तक वैरिएबल वास्तव में उस प्रकार का होता है जिसे आप इसे कास्टिंग कर रहे हैं, अन्यथा आपके हाथों पर गड़बड़ी होगी।

फिर भी के साथ कास्टिंग as! आपके कोड को संकलित करने की अनुमति देगा। के as? कास्टिंग करके as? एक अलग कहानी है। वास्तव में, के as? अपने Int को एक साथ एक पूरी तरह से अलग डेटा प्रकार के रूप में घोषित करता है।

अब यह Optional(0)

और यदि आपने कभी अपना होमवर्क लिखने की कोशिश की है

1 + Optional(1) = 2

आपके गणित के शिक्षक ने आपको "एफ" दिया होगा। स्विफ्ट के साथ ही। स्विफ्ट को छोड़कर आपको ग्रेड देने के बजाए संकलित नहीं किया जाएगा। क्योंकि दिन के अंत में वैकल्पिक वास्तव में शून्य हो सकता है

सुरक्षा पहले बच्चे।





ios8