स्विफ्ट: स्विच मामले में वैकल्पिक मूल्य के खिलाफ परीक्षण


94

स्विफ्ट में, मैं एक स्विच स्टेटमेंट में एक केस कैसे लिख सकता हूं जो किसी वैकल्पिक की सामग्री के खिलाफ स्विच किए जा रहे मूल्य का परीक्षण करता है , यदि वैकल्पिक हो तो मामले पर लंघनnil ?

यहां बताया गया है कि मैं इसकी कल्पना कर सकता हूं:

let someValue = 5
let someOptional: Int? = nil

switch someValue {
case someOptional:
    // someOptional is non-nil, and someValue equals the unwrapped contents of someOptional
default:
    // either, someOptional is nil, or someOptional is non-nil but someValue does not equal the unwrapped contents of someOptional
}

अगर मैं सिर्फ यह वास्तव में इस तरह लिखते हैं, संकलक शिकायत है कि someOptionalunwrapped नहीं है, लेकिन मैं स्पष्ट रूप से इसे खोलना जोड़कर यदि !अंत करने के लिए, मैं निश्चित रूप से एक क्रम त्रुटि मिलती है किसी भी समय someOptionalहोता है nil?इसके बजाय जोड़ने !से मुझे कुछ समझ में आएगा (वैकल्पिक जंजीर की भावना में, मुझे लगता है), लेकिन संकलक त्रुटि को दूर नहीं करता है (यानी वास्तव में वैकल्पिक को खोलना नहीं है)।

जवाबों:


113

वैकल्पिक enumइस तरह से है:

enum Optional<T> : Reflectable, NilLiteralConvertible {
    case none
    case some(T)

    // ...
}

तो आप उन्हें हमेशा की तरह "एसोसिएटेड वैल्यूज़" के मेल खाने वाले पैटर्न से मिला सकते हैं:

let someValue = 5
let someOptional: Int? = nil

switch someOptional {
case .some(someValue):
    println("the value is \(someValue)")
case .some(let val):
    println("the value is \(val)")
default:
    println("nil")
}

यदि आप गार्ड अभिव्यक्तिsomeValue का उपयोग करके मैच चाहते हैं , तो :

switch someValue {
case let val where val == someOptional:
    println(someValue)
default:
    break
}

और स्विफ्ट> 2.0 के लिए

switch someValue {
case let val where val == someOptional:
    print("matched")
default:
    print("didn't match; default")        
}

5
ध्यान दें कि स्विफ्ट 3 में, कुछ / कोई भी लोअरकेस नहीं है, अर्थात आप इसका उपयोग करेंगे। इसके बजाय कुछ। कुछ
एडम

55

Xcode 7 के रूप में, "एक नए x?पैटर्न का उपयोग वैकल्पिक के खिलाफ मैच के लिए एक पर्याय के रूप में मिलान के लिए किया जा सकता है .some(x)"। इसका अर्थ है कि स्विफ्ट 2 और बाद में रिंटारो के उत्तर की निम्नलिखित भिन्नता भी काम करेगी:

let knownValue = 5

switch someOptional {
case knownValue?:
    // Contents of someOptional are knownValue, defined above.
case let otherValue?:
    // Contents of someOptional are *any* non-nil value not already tested for.
    // Unwrapped contents are assigned to otherValue for use inside this case.
default:
    // someOptional is nil.
}

3
सवाल एक वैकल्पिक के खिलाफ गैर-वैकल्पिक मूल्य से मेल खाने के बारे में है, यह उत्तर अन्य तरह से है।
मार्टिन आर

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

2
मैं थोड़ा खोया हुआ हूं। आपके पहले दो मामलों में क्या अंतर है? someValue?कुछ अन्य परिभाषित मूल्य है, लेकिन case let val?सिर्फ सुरक्षित अलिखित संस्करण है someOptional!
हनी

@ यह एक वास्तविक दुनिया कोड उदाहरण नहीं है; यह केवल रिंटारो के उत्तर पर भिन्नता है। तो उससे यह सवाल पूछें कि मेरा जवाब कार्यात्मक रूप से उसके / उसके कोड के बराबर है। यदि आप हालांकि रिंटारो से पूछना चाहते थे, तो मेरा मानना ​​है कि उत्तर होगा 1. यह लिंक किए गए Apple डॉक्स में क्या है? 2. यह केवल वाक्य-विन्यास को प्रदर्शित करता है; यह एक विशिष्ट गणना या व्यावसायिक तर्क लक्ष्य को पूरा नहीं करता है।
स्लिप डी। थॉम्पसन

@ हनी इसके अलावा, रिंटारो का जवाब मूल रूप से स्विफ्ट 1.x के लिए लिखा गया था और स्विफ्ट 2 के लिए अपडेट किया गया था। यह संभव है कि letअब बिना संस्करण संकलित हो। मुझे अभी याद नहीं है कि दिन में क्यों काम किया होगा।
स्लिप डी। थॉम्पसन

10

में स्विफ्ट 4 आप उपयोग कर सकते ExpressibleByNilLiteral: वैकल्पिक वैकल्पिक wrappe को एप्पल के

https://developer.apple.com/documentation/swift/optional

उदाहरण

enum MyEnum {
    case normal
    case cool
}

कुछ

let myOptional: MyEnum? = MyEnum.normal

switch smyOptional {
    case .some(.normal): 
    // Found .normal enum
    break

    case .none: 
    break

    default:
    break
}

कोई नहीं

let myOptional: MyEnum? = nil

switch smyOptional {
    case .some(.normal): 
    break

    case .none: 
    // Found nil
    break

    default:
    break
}

चूक

let myOptional: MyEnum? = MyEnum.cool

switch smyOptional {
    case .some(.normal): 
    break

    case .none: 
    break

    default:
    // Found .Cool enum
    break
}

मान के साथ Enum

enum MyEnum {
    case normal(myValue: String)
    case cool
}

कुछ मूल्य

let myOptional: MyEnum? = MyEnum.normal("BlaBla")

switch smyOptional {
case .some(.normal(let myValue)) where myValue == "BlaBla":
    // Here because where find in my myValue "BlaBla"
    break

// Example for get value
case .some(.normal(let myValue)):
    break

// Example for just know if is normal case enum
case .some(.normal):
    break

case .none:
    break

default:

    break
}

आप उल्लेख करते हैं, ExpressibleByNilLiteralलेकिन फिर वास्तव में एनम घोषणाओं आदि में इसका उपयोग नहीं किया जाता है, वह क्या है?
pkamb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.