एक वैकल्पिक बूल के मूल्य की जाँच करना


88

जब मैं जांच करना चाहता हूं कि क्या एक वैकल्पिक बूल सही है, तो ऐसा करने से काम नहीं होता है:

var boolean : Bool? = false
if boolean{
}

यह इस त्रुटि का परिणाम है:

वैकल्पिक प्रकार '@IvalueBool?' एक बूलियन के रूप में इस्तेमाल नहीं किया जा सकता है; इसके बजाय '! nil' के लिए परीक्षण करें

मैं शून्य के लिए जाँच नहीं करना चाहता; मैं जांच करना चाहता हूं कि क्या लौटाया गया मूल्य सही है

if boolean == trueअगर मुझे वैकल्पिक बूल के साथ काम करना है तो क्या मुझे हमेशा करना होगा?

चूंकि वैकल्पिक BooleanTypeअब और अनुरूप नहीं हैं, इसलिए संकलक को नहीं पता होना चाहिए कि मैं बूल के मूल्य की जांच करना चाहता हूं?


चूंकि बूलियंस इक्विटेबल प्रोटोकॉल के अनुरूप हैं, तो आप एक वैकल्पिक की तुलना गैर-वैकल्पिक से कर सकते हैं। यहां
हनी

जवाबों:


192

वैकल्पिक बूलियन्स के साथ, चेक को स्पष्ट करना आवश्यक है:

if boolean == true {
    ...
}

अन्यथा आप वैकल्पिक खोल सकते हैं:

if boolean! {
    ...
}

लेकिन जो रनटाइम अपवाद उत्पन्न करता है अगर बूलियन है nil- इसे रोकने के लिए:

if boolean != nil && boolean! {
    ...
}

बीटा 5 से पहले यह संभव था, लेकिन इसे जारी नोटों में बताया गया है:

वैकल्पिक अब स्पष्ट रूप से सही मूल्यांकन नहीं करते हैं, जब उनके पास मूल्य और असत्य है जब वे नहीं करते हैं, वैकल्पिक बूल मूल्यों के साथ काम करते समय भ्रम से बचने के लिए। इसके बजाय, एनआईएल के साथ एक स्पष्ट जाँच करें == या! = ऑपरेटरों को यह पता लगाने के लिए कि क्या वैकल्पिक में कोई मान है।

परिशिष्ट: @MartinR द्वारा सुझाए गए अनुसार, 3 विकल्प के लिए एक और अधिक कॉम्पैक्ट भिन्नता coalescing संचालक का उपयोग कर रहा है:

if boolean ?? false {
    // this code runs only if boolean == true
}

जिसका अर्थ है: यदि बूलियन शून्य नहीं है, तो अभिव्यक्ति बूलियन मान का मूल्यांकन करती है (यानी अनगढ़ बूलियन मूल्य का उपयोग करके), अन्यथा अभिव्यक्ति का मूल्यांकन होता है false


4
तीसरा विकल्प पसंदीदा समाधान है क्योंकि यह कोड के इरादे को व्यक्त करने का सबसे अच्छा तरीका है। उपयोग if letकरने से भी काम होगा।
सुल्तान

29
तीसरे विकल्प का एक प्रकार है, "नील कोलेसिंग ऑपरेटर ??" का उपयोग करते हुए if boolean ?? false { ... }:।
मार्टिन आर

4
लेकिन अगर मैं इसे नकारना चाहता हूं तो यह हास्यास्पद if !(boolean ?? true) { ... }
एंड्रियास

2
मजबूरन एक बेहद बुरा विचार सामने लाया। इससे हमेशा बचना चाहिए।
मैथ्यू रीगलर

4
पहले विकल्प में क्या गलत है? मेरे लिए यह सबसे अच्छा तरीका है।
वाहिद अमीरी

43

वैकल्पिक बंधन

स्विफ्ट 3 और 4

var booleanValue : Bool? = false
if let booleanValue = booleanValue, booleanValue {
    // Executes when booleanValue is not nil and true
    // A new constant "booleanValue: Bool" is defined and set
    print("bound booleanValue: '\(booleanValue)'")
}

स्विफ्ट 2.2

var booleanValue : Bool? = false
if let booleanValue = booleanValue where booleanValue {
    // Executes when booleanValue is not nil and true
    // A new constant "booleanValue: Bool" is defined and set
    print("bound booleanValue: '\(booleanValue)'")
}

कोड let booleanValue = booleanValueरिटर्न है और falseयदि ब्लॉक निष्पादित नहीं करता है। यदि ऐसा नहीं है , तो यह कोड प्रकार (वैकल्पिक के बजाय ) नाम के एक नए चर को परिभाषित करता है ।booleanValuenilifbooleanValuenilbooleanValueBoolBool?

स्विफ्ट 3 और 4 कोड booleanValue(और स्विफ्ट 2.2 कोड where booleanValue) नए booleanValue: Boolचर का मूल्यांकन करता है। यदि यह सही है, तो ifब्लॉक booleanValue: Boolकार्यक्षेत्र में नए परिभाषित चर के साथ निष्पादित होता है ( ifब्लॉक के भीतर फिर से बाध्य मान को संदर्भित करने के लिए विकल्प की अनुमति देता है )।

नोट: यह एक स्विफ्ट कन्वेंशन है जो निरंतर स्थिरांक / वैरिएबल को वैसा ही नाम देता है जैसे वैकल्पिक स्थिरांक / चर let booleanValue = booleanValue। इस तकनीक को वेरिएबल शैडोइंग कहा जाता है । आप सम्मेलन से टूट सकते हैं और कुछ का उपयोग कर सकते हैं let unwrappedBooleanValue = booleanValue, unwrappedBooleanValue। मैं इसे समझने में मदद करने के लिए इंगित करता हूं कि क्या हो रहा है। मैं वैरिएबल शैडोइंग का उपयोग करने की सलाह देता हूं।

 

अन्य दृष्टिकोण

निल बँधना

इस विशिष्ट मामले के लिए निल coalescing स्पष्ट है

var booleanValue : Bool? = false
if booleanValue ?? false {
    // executes when booleanValue is true
    print("optional booleanValue: '\(booleanValue)'")
}

के लिए जाँच के falseरूप में स्पष्ट नहीं है

var booleanValue : Bool? = false
if !(booleanValue ?? false) {
    // executes when booleanValue is false
    print("optional booleanValue: '\(booleanValue)'")
}

नोट: if !booleanValue ?? falseसंकलन नहीं है।

 

बल अलिखित वैकल्पिक (से बचें)

फोर्स अनप्रॉपिंग से यह संभावना बढ़ जाती है कि कोई व्यक्ति भविष्य में एक बदलाव करेगा जो संकलित करता है लेकिन रनटाइम पर क्रैश होता है। इसलिए, मैं कुछ इस तरह से बचना होगा:

var booleanValue : Bool? = false
if booleanValue != nil && booleanValue! {
    // executes when booleanValue is true
    print("optional booleanValue: '\(booleanValue)'")
}

 

एक सामान्य दृष्टिकोण

हालांकि इस ढेर अतिप्रवाह सवाल पूछता है कि विशेष रूप से एक जांच करने का तरीका Bool?है trueएक के भीतर ifबयान, यह सही गलत या अन्य भाव के साथ unwrapped मूल्य के संयोजन के लिए जाँच करें कि क्या एक सामान्य दृष्टिकोण की पहचान करने के लिए उपयोगी है।

जैसा कि अभिव्यक्ति अधिक जटिल हो जाती है, मुझे वैकल्पिक बाध्यकारी दृष्टिकोण अधिक लचीला और अन्य दृष्टिकोणों की तुलना में समझने में आसान लगता है। नोट किसी भी वैकल्पिक प्रकार (के साथ कि वैकल्पिक बाध्यकारी काम करता है Int?, String?, आदि)।


मुझे छोरों के लिए एक वैकल्पिक के साथ बूलियन अभिव्यक्तियों का उपयोग करने में कठिनाई हो रही है। शून्य कोलाइज़ करने वाला ऑपरेटर काम करता है, लेकिन यह गड़बड़ है और त्रुटि प्रवण है। क्या उपयोग करने का कोई तरीका है if let?
जर्बगा

@jbaraga, कृपया जिस लूप के बारे में सोच रहे हैं, उसका एक उदाहरण पोस्ट करें।
मोबाइल दान

एक स्टैक के रूप में एक सरणी का उपयोग करने में, मैं एक शर्त पूरी होने तक मूल्यों को पॉप करना चाहता हूं, या स्टैक खाली है। उदाहरण के लिए,while array.last < threshold { array.removeLast() }
२१:४bar पर जर्बगा

आप इसका if, let, whereउपयोग करके स्टैक प्रोसेसिंग को पूरा कर सकते हैं : while let last = array.last where last < threshold { array.removeLast() }स्विफ्ट 2 में या while let last = array.last, last < threshold { array.removeLast() }स्विफ्ट 3. में
मोबाइल दान

यह बेहतर है, धन्यवाद। मुझे पता नहीं था while let
जर्बगा

1
var enabled: Bool? = true

if let enabled = enabled, enabled == true {
    print("when is defined and true at the same moment")
}

if enabled ?? false {
    print("when is defined and true at the same moment")
}

if enabled == .some(true) {
    print("when is defined and true at the same moment")
}

if enabled == (true) {
    print("when is defined and true at the same moment")
}

if case .some(true) = enabled {
    print("when is defined and true at the same moment")
}

if enabled == .some(false) {
    print("when is defined and false at the same moment")
}

if enabled == (false) {
    print("when is defined and false at the same moment")
}

if enabled == .none {
    print("when is not defined")
}

if enabled == nil {
    print("when is not defined")
}

0

मुझे एक और उपाय मिला, बूलियन ऑपरेटरों को ओवरलोड करना। उदाहरण के लिए:

public func < <T: Comparable> (left: T?, right: T) -> Bool {
    if let left = left {
        return left < right
    }
    return false
}

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


1
क्षमा करें, मूल पोस्ट को देखते हुए, यह उस विशिष्ट प्रश्न का उत्तर नहीं देता है, बल्कि यह प्रश्न जो मैंने अपनी पिछली टिप्पणी में उठाया था।
जर्बगा

मैं इस अधिभार का उपयोग करने के बारे में बहुत सावधान रहूंगा, क्योंकि ऐसे मामले हो सकते हैं जहां आप नहीं चाहते कि नील को "गैर-शून्य मूल्य" से अधिक माना जाए (आप कुछ संदर्भों में विपरीत परिणाम चाहते हैं, या संभवतः वैकल्पिक हो सकते हैं पूरी तरह से संभालना)। इसके बजाय सामान्य अलौकिकता का उपयोग आपको स्पष्ट रूप से संबोधित करने के लिए मजबूर करता है कि आप हर मामले में निलों को कैसे संभालना चाहते हैं, इसलिए आपको अप्रत्याशित परिणामों में भाग लेने की संभावना कम है।
जॉन मोंटगोमरी

0

उत्तर जो मुझे पढ़ने में सबसे आसान लगा, वह है फंक्शन को परिभाषित करना। बहुत जटिल नहीं है लेकिन काम करता है।

func isTrue(_ bool: Bool?) -> Bool {
    guard let b = bool else {
        return false
    }
    return b
}

उपयोग:

let b: Bool? = true
if isTrue(b) {
    // b exists and is true
} else {
    // b does either not exist or is false
}

0

जैसा कि एंटोनियो ने कहा

वैकल्पिक अब स्पष्ट रूप से सही मूल्यांकन नहीं करते हैं, जब उनके पास मूल्य और असत्य है जब वे नहीं करते हैं, वैकल्पिक बूल मूल्यों के साथ काम करते समय भ्रम से बचने के लिए। इसके बजाय, एनआईएल के साथ एक स्पष्ट जाँच करें == या! = ऑपरेटरों को यह पता लगाने के लिए कि क्या वैकल्पिक में कोई मान है।

मैंने कुछ घंटों तक कोड की एक पंक्ति को समझने की कोशिश की, जिस पर मैंने ठोकर खाई, लेकिन इस धागे ने मुझे सही रास्ते पर ला खड़ा किया।

यह उद्धरण अगस्त 2014 से है , और उसके बाद से Apple ने SE-0102 के प्रस्ताव काNever पालन किया और बाद में इसे इक्विटेबल, हसबल, एरर एंड कम्पैरेबल के अनुरूप बनाया गया।

अब यह जांचना संभव है कि क्या बुलियन nilउपयोग कर रहा है Never?:


var boolean: Bool? = false
boolean is Never? // false
boolean = true
boolean is Never? // false
boolean = nil
boolean is Never? // true

आप वास्तव में किसी अन्य निर्जन प्रकार का उपयोग कर सकते हैं:

public enum NeverEver { }
var boolean: Bool? = false
boolean is NeverEver? // false
boolean = true
boolean is NeverEver? // false
boolean = nil
boolean is NeverEver? // true

कहा जा रहा है कि, अब एक संपत्ति आवरण का उपयोग करना भी संभव है :

@propertyWrapper struct OptionalBool {
    public var wrappedValue: Bool?
    public var projectedValue: Bool { wrappedValue ?? false }
    public init(wrappedValue: Bool?) {
        self.wrappedValue = wrappedValue
    }
}

struct Struct {
    @OptionalBool var predicate: Bool?
    var description: String {
        if $predicate {
            return "predicate is true"
        }
        return "predicate is false"
    }
}

var object = Struct()
object.description // "predicate is false"
object.predicate = false
object.description // "predicate is false"
object.predicate = true
object.description // "predicate is true"

या और भी:

@propertyWrapper struct OptionalBool {
    var wrappedValue: Bool?
    var projectedValue: OptionalBool { self }
    var isNil: Bool { wrappedValue is Never? }
    var value: Bool { wrappedValue ?? false }
    
    init(wrappedValue: Bool?) {
        self.wrappedValue = wrappedValue
    }
}

struct Struct {
    @OptionalBool var predicate: Bool?
    var description: String {
        if $predicate.value {
            return "predicate is true"
        }
        if !$predicate.isNil {
            return "predicate is false"
        }
        return "predicate is nil"
    }
}

var object = Struct()
object.description // "predicate is nil"
object.predicate = false
object.description // "predicate is false"
object.predicate = true
object.description // "predicate is true"

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