मुद्रण वैकल्पिक चर


118

मैं कोड की इन पंक्तियों के साथ कोशिश कर रहा हूं

class Student {
    var name: String
    var age: Int?

    init(name: String) {
        self.name = name
    }

    func description() -> String {
        return age != nil ? "\(name) is \(age) years old." : "\(name) hides his age."
    }
}

var me = Student(name: "Daniel")
println(me.description())
me.age = 18
println(me.description())

उपरोक्त कोड अनुसरण के रूप में उत्पन्न करता है

Daniel hides his age.
Daniel is Optional(18) years old.

मेरा सवाल यह है कि वहाँ वैकल्पिक (18) क्यों है, मैं वैकल्पिक और सिर्फ मुद्रण कैसे निकाल सकता हूं

Daniel is 18 years old.

जवाबों:


190

आपको यह समझना होगा कि एक वैकल्पिक वास्तव में क्या है। कई स्विफ्ट शुरुआती लोग सोचते हैं var age: Int?कि उम्र एक ऐसा इंट है जिसका मूल्य हो सकता है या नहीं। लेकिन इसका मतलब है कि उम्र एक वैकल्पिक है जो एक इंट पकड़ सकता है या नहीं हो सकता है।

अपने description()फ़ंक्शन के अंदर आप इंट को प्रिंट नहीं करते हैं, बल्कि इसके बजाय आप वैकल्पिक प्रिंट करते हैं। अगर आप Int को प्रिंट करना चाहते हैं तो आपको Optional खोलना होगा। आप एक वैकल्पिक को खोलने के लिए "वैकल्पिक बाध्यकारी" का उपयोग कर सकते हैं:

if let a = age {
 // a is an Int
}

यदि आप सुनिश्चित हैं कि वैकल्पिक एक वस्तु रखता है, तो आप "जबरन अलिखित" का उपयोग कर सकते हैं:

let a = age!

या आपके उदाहरण में, चूंकि आपके पास पहले से ही विवरण फ़ंक्शन में शून्य के लिए एक परीक्षण है, आप इसे केवल इसे बदल सकते हैं:

func description() -> String {
    return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}

मुझे लगता है कि उदाहरण थोड़ा बेहतर होगा अगर आपने इसे उपयोग करने के लिए बदल दियाif let age = age { return ""} else { return "" }
kubi

13
+1 के लिए:Many Swift beginners think var age: Int? means that age is an Int which may or may not have a value. But it means that age is an Optional which may or may not hold an Int.
lee

18

एक वैकल्पिक का अर्थ है कि स्विफ्ट पूरी तरह से निश्चित नहीं है यदि मूल्य प्रकार से मेल खाती है: उदाहरण के लिए, इंट? इसका मतलब है कि स्विफ्ट पूरी तरह से निश्चित नहीं है कि नंबर एक इंट है या नहीं।

इसे हटाने के लिए, तीन तरीके हैं जिन्हें आप नियोजित कर सकते हैं।

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

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

यदि आप एक वैकल्पिक को बलपूर्वक खोलते हैं और यह शून्य के बराबर होता है, तो आप इस क्रैश त्रुटि का सामना कर सकते हैं:

यहां छवि विवरण दर्ज करें

यह आवश्यक रूप से सुरक्षित नहीं है, इसलिए यहां एक विधि है जो दुर्घटना को रोक सकती है यदि आप प्रकार और मूल्य के बारे में निश्चित नहीं हैं:

इस समस्या के लिए तरीके 2 और तीन सुरक्षित हैं।

2) द अनप्लान्टली अनप्रोक्ड ऑप्शनल

 if let unwrappedAge = age {

 // continue in here

 }

ध्यान दें कि अपरिवर्तित प्रकार अब Int के बजाय Int , है ?

3) गार्ड का बयान

 guard let unwrappedAge = age else { 
   // continue in here
 }

यहां से, आप आगे जा सकते हैं और अलिखित चर का उपयोग कर सकते हैं। यदि आप वैरिएबल के प्रकार के बारे में सुनिश्चित हैं, तो केवल अनप्रेप (a!) के साथ ही यह सुनिश्चित करें।

आपकी परियोजना के लिए शुभकामनाएं!


1
वापसी की उम्र का उपयोग? "(नाम) है (उम्र!) साल पुराना है।" : "(नाम) अपनी उम्र छुपाता है।"
'17:36 पर leedream

1
मेरे पास एक मुद्दे के साथ एक सिरदर्द बचा लिया। आपको पर्याप्त धन्यवाद नहीं दे सकता।
ब्रूनो रिकिलस

8

परीक्षण / डिबगिंग उद्देश्यों के लिए मैं अक्सर वैकल्पिक nilमानों के लिए परीक्षण किए बिना स्ट्रिंग के रूप में वैकल्पिक आउटपुट करना चाहता हूं, इसलिए मैंने एक कस्टम ऑपरेटर बनाया।

मैंने एक और प्रश्न में इस उत्तर को पढ़ने के बाद चीजों को और बेहतर किया ।

fileprivate protocol _Optional {
    func unwrappedString() -> String
}

extension Optional: _Optional {
    fileprivate func unwrappedString() -> String {
        switch self {
        case .some(let wrapped as _Optional): return wrapped.unwrappedString()
        case .some(let wrapped): return String(describing: wrapped)
        case .none: return String(describing: self)
        }
    }
}

postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
    return x.unwrappedString
}

जाहिर है कि ऑपरेटर (और इसके गुण) को आपकी पसंद के अनुरूप बनाया जा सकता है, या आप इसके बजाय इसे एक समारोह बना सकते हैं। वैसे भी, यह आपको इस तरह से सरल कोड लिखने में सक्षम बनाता है:

var d: Double? = 12.34
print(d)     // Optional(12.34)
print(d~?)   // 12.34
d = nil
print(d~?)   // nil

दूसरे व्यक्ति के प्रोटोकॉल विचार को एकीकृत करते हुए इसने नेस्टेड वैकल्पिक के साथ भी काम किया है, जो अक्सर वैकल्पिक चेनिंग का उपयोग करते समय होता है। उदाहरण के लिए:

let i: Int??? = 5
print(i)              // Optional(Optional(Optional(5)))
print("i: \(i~?)")    // i: 5

1
स्विफ्ट 3 के रूप में आप स्विफ्ट मानक लाइब्रेरी फ़ंक्शन डिबगप्रिंट (_: विभाजक: टर्मिनेटर :) का उपयोग कर सकते हैं। यह हालांकि डबल कोट्स में स्ट्रिंग प्रिंट करेगा।

@psmythirl: जानकर अच्छा लगा! हालाँकि कभी-कभी आप एक वैकल्पिक विकल्प को Stringकहीं और पास या एम्बेड करना चाहते हैं (उदाहरण के लिए लॉग / त्रुटि संदेश)।
जेरेमी

प्रिंट (डी
ऐज़

7

अपडेट करें

बस उपयोग करें me.age ?? "Unknown age!"। यह 3.0.2 में काम करता है।

पुराना उत्तर

बिना बल प्रयोग के बिना (कोई मच सिग्नल / क्रैश यदि शून्य हो) ऐसा करने का एक और अच्छा तरीका होगा:

(result["ip"] ?? "unavailable").description

result["ip"] ?? "unavailable" काम भी होना चाहिए, लेकिन यह 2.2 में नहीं, कम से कम

बेशक, जो भी सूट हो, उसके साथ "अनुपलब्ध" को बदल दें: "नील", "नहीं मिला" आदि


4

के age!बजाय वैकल्पिक उपयोग को अनचेक करने के लिए age। वर्तमान में आपका मुद्रण वैकल्पिक मूल्य है जो हो सकता है nil। Thats क्यों यह साथ लिपटे Optional


4

स्विफ्ट Optionalमें ऐसा कुछ है जो nilकुछ मामलों में हो सकता है। यदि आप 100% सुनिश्चित हैं कि एक variableहमेशा कुछ मूल्य होगा और चर के साथ nilजोड़ने !को वापस नहीं करेंगे इसे खोल देना है।

अन्य मामले में यदि आप मूल्य के बारे में अधिक निश्चित नहीं हैं, तो एक if letब्लॉक जोड़ें या guardसुनिश्चित करें कि मूल्य मौजूद है अन्यथा यह दुर्घटना में हो सकता है।

के लिए if letब्लॉक:

if let abc = any_variable {
 // do anything you want with 'abc' variable no need to force unwrap now.
}

के लिए guardबयान:

guard अगर हालत नहीं मिले तो नियंत्रण वापस करने के लिए एक सशर्त संरचना है।

मैं कई स्थितियों में ब्लॉक guardओवर का उपयोग करना पसंद करता हूं if letक्योंकि यह हमें वापस करने की अनुमति देता है functionयदि कोई विशेष मूल्य मौजूद नहीं है। जैसे जब कोई फ़ंक्शन होता है जहां एक चर अस्तित्व के लिए अभिन्न होता है, तो हम गार्ड स्टेटमेंट में इसकी जांच कर सकते हैं और इसकी वापसी मौजूद नहीं है। अर्थात;

guard let abc = any_variable else { return }

अगर वेरिएबल मौजूद है तो हम गार्ड स्कोप के बाहर फंक्शन में 'एबीसी' का उपयोग कर सकते हैं।


3

ageवैकल्पिक प्रकार है: Optional<Int>इसलिए यदि आप इसे शून्य से तुलना करते हैं तो यह हर बार गलत होता है यदि इसका कोई मूल्य है या यदि यह नहीं है। मूल्य प्राप्त करने के लिए आपको वैकल्पिक को खोलना होगा।

आपके उदाहरण में आप नहीं जानते कि इसमें कोई मूल्य है ताकि आप इसके बजाय इसका उपयोग कर सकें:

if let myAge = age {
    // there is a value and it's currently undraped and is stored in a constant
}
else {
   // no value
}

3

मैंने एक अन्य दृश्य नियंत्रक से स्ट्रिंग (संपत्ति) के मूल्य को प्रिंट करने के लिए ऐसा किया।

ViewController.swift

var testString:NSString = "I am iOS Developer"

SecondViewController.swift

var obj:ViewController? = ViewController(nibName: "ViewController", bundle: nil)
print("The Value of String is \(obj!.testString)")

परिणाम :

The Value of String is I am iOS Developer

2
आप एक वैकल्पिक खोलना मजबूर नहीं करना चाहिए
ई Riddie


3

डिफ़ॉल्ट मान होने पर:

print("\(name) is \(age ?? 0) years old")

या जब नाम वैकल्पिक हो:

print("\(name ?? "unknown") is \(age) years old")


1

मैं अपने टेबलव्यू कोशिकाओं में वैकल्पिक ("स्ट्रिंग") प्राप्त कर रहा था।

पहला उत्तर बहुत अच्छा है। और मुझे यह पता लगाने में मदद की। यहाँ है कि मैं क्या किया, मेरी तरह वहाँ बाहर बदमाशों की मदद करने के लिए।

चूंकि मैं अपने कस्टम ऑब्जेक्ट में एक सरणी बना रहा हूं, मुझे पता है कि इसमें हमेशा पहली स्थिति में आइटम होंगे, इसलिए मैं इसे दूसरे चर में अनप्लग कर सकता हूं। फिर उस चर को प्रिंट करने के लिए, या मेरे मामले में, टेबलव्यू सेल टेक्स्ट पर सेट करें।

let description = workout.listOfStrings.first!
cell.textLabel?.text = description

अब इतना आसान लगता है, लेकिन मुझे यह पता लगाने में थोड़ा समय लगा।


-1

यह इस प्रश्न का सटीक उत्तर नहीं है, लेकिन इस तरह के मुद्दे का एक कारण है। मेरे मामले में, मैं "अगर लेट" और "गार्ड लेट" के साथ एक स्ट्रिंग से वैकल्पिक को हटाने में सक्षम नहीं था।

इसलिए स्विफ्ट में एक स्ट्रिंग से वैकल्पिक हटाने के लिए Any के बजाय AnyObject का उपयोग करें ।

कृपया उत्तर के लिए लिंक देखें।

https://stackoverflow.com/a/51356716/8334818

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.