स्विफ्ट में एक वैकल्पिक के लिए एक डिफ़ॉल्ट मान प्रदान करना?


141

स्विफ्ट में वैकल्पिक से निपटने के लिए मुहावरा अत्यधिक क्रियात्मक लगता है, यदि आप जो करना चाहते हैं वह उस मामले में एक डिफ़ॉल्ट मूल्य प्रदान करता है जहां यह शून्य है:

if let value = optionalValue {
    // do something with 'value'
} else {
    // do the same thing with your default value
}

जिसमें अनावश्यक रूप से डुप्लिकेट कोड शामिल है, या

var unwrappedValue
if let value = optionalValue {
    unwrappedValue = value
} else {
    unwrappedValue = defaultValue
}

जिसकी आवश्यकता unwrappedValueनिरंतर नहीं है।

स्काला के विकल्प मोनाड (जो मूल रूप से स्विफ्ट के वैकल्पिक के समान विचार है) में getOrElseइस उद्देश्य के लिए विधि है :

val myValue = optionalValue.getOrElse(defaultValue)

क्या मैं कुछ भूल रहा हूँ? क्या स्विफ्ट के पास पहले से ही ऐसा करने का एक कॉम्पैक्ट तरीका है? या, असफल होना, क्या getOrElseवैकल्पिक के लिए विस्तार में परिभाषित करना संभव है ?


जवाबों:


289

अपडेट करें

Apple अब एक coalescing ऑपरेटर जोड़ा गया है:

var unwrappedValue = optionalValue ?? defaultValue

इस मामले में टर्नरी ऑपरेटर आपका दोस्त है

var unwrappedValue = optionalValue ? optionalValue! : defaultValue

आप वैकल्पिक एनम के लिए अपना खुद का एक्सटेंशन भी दे सकते हैं:

extension Optional {
    func or(defaultValue: T) -> T {
        switch(self) {
            case .None:
                return defaultValue
            case .Some(let value):
                return value
        }
    }
}

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

optionalValue.or(defaultValue)

हालांकि, मैं टर्नरी ऑपरेटर से चिपके रहने की सलाह देता हूं क्योंकि अन्य डेवलपर्स इस orपद्धति की जांच किए बिना बहुत जल्दी समझ जाएंगे

नोट : मैं एक शुरू कर दिया मॉड्यूल इस तरह आम सहायकों को जोड़ने के लिए orपर Optionalतेजी से करने के लिए।


मेरी विवशता मुझे दिखाती है कि unwrappedValueस्विफ्ट 1.2: var unwrappedValue = optionalValue ? optionalValue! : defaultValue(xcode 6 beta 4) में इस प्रकार का अभी भी वैकल्पिक प्रकार है । क्या यह बदल गया है?
सिम्पलजी

2
मैं अपने संस्करण पर गलत हूं। मैं 6.4 पर हूं। अवगत रहें: ??डिफ़ॉल्ट प्रकार का अनुमान व्यवहार यह है कि यह एक वैकल्पिक रिटर्न देता है, जो कि आप आमतौर पर नहीं चाहते हैं। आप चर को गैर-वैकल्पिक घोषित कर सकते हैं और यह अच्छी तरह से काम करता है।
सिम्पलजी

29

अगस्त 2014 तक स्विफ्ट के पास कॉइलसिंग ऑपरेटर (??) है जो इसकी अनुमति देता है। उदाहरण के लिए, वैकल्पिक स्ट्रिंग myOptional के लिए आप लिख सकते हैं:

result = myOptional ?? "n/a"

4

अगर आपने लिखा है:

let result = optionalValue ?? 50

और optionalValue != nilतब भी resultहोगा optionalऔर भविष्य में आपको इसे खोलना होगा

लेकिन आप ऑपरेटर लिख सकते हैं

infix operator ??? { associativity left precedence 140 }

func ???<T>(optLeft:T?, right:T!) -> T!
{
    if let left = optLeft
    {
        return left
    }
    else { return right}
}

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

 let result = optionalValue ??? 50

और जब होगा optionalValue != nilतब resultहोगाunwraped


3

निम्नलिखित काम करने लगता है

extension Optional {
    func getOrElse<T>(defaultValue: T) -> T {
        if let value = self? {
            return value as T
        } else {
            return defaultValue
        }
    }
}

हालांकि, कास्ट करने की आवश्यकता value as Tएक बदसूरत हैक है। आदर्श रूप से, यह दावा करने का एक तरीका होना चाहिए कि Tवैकल्पिक में निहित प्रकार के समान है। जैसा कि यह खड़ा है, TgetOrElse को दिए गए पैरामीटर के आधार पर हीनिंग सेट टाइप करें , और फिर रनटाइम में विफल रहता है यदि यह वैकल्पिक से मेल नहीं खाता है और वैकल्पिक गैर-शून्य है:

let x: Int?

let y = x.getOrElse(1.414) // y inferred as Double, assigned 1.414

let a: Int? = 5

let b: Double = a.getOrElse(3.14) // Runtime failure casting 5 to Double

आपको Tविधि के लिए निर्दिष्ट करने की आवश्यकता नहीं है । यह वास्तव में Tवैकल्पिक से मौजूदा को ओवरराइड करता है । आप बस कर सकते हैं: func getOrElse(defaultValue: T) -> Tतब टी वैकल्पिक के वास्तविक मूल्य प्रकार को संदर्भित करता है और आपको इसे टाइप करने की ज़रूरत नहीं है
18

धन्यवाद! मुझे आपकी प्रतिक्रिया के दूसरे भाग से वास्तव में अनुमान है। क्या यह जानने का कोई तरीका है कि वैकल्पिक की परिभाषा का यह पता लगाया जाए कि जेनेरिक प्रकार को किस रूप Tमें परिभाषित किया गया है? (अधिवेशन के आधार पर केवल अनुमान से परे)
वेस कैंपेन

यदि आप OptionalXcode के अंदर कमांड-क्लिक करते हैं, तो आप देखेंगे कि इसे परिभाषित किया गया हैenum Optional<T>
drewag

ओह, उत्कृष्ट। मुझे अनुमान लगाना चाहिए था। वहां की परिभाषाएं उपयोगी होंगी; बहुत सारी चीजें हैं जो अभी तक प्रलेखन में नहीं हैं। एक बार फिर धन्यवाद।
वेस कैंपेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.