2015-11-12 4 views
20

में हालत मैं एक enum है:नहीं 'यदि यह मामला' बयान

enum E { 
    case A, B, C(Int) 
} 

let a: E = .A 

यहाँ अगर a के बराबर होती है .B

if case .B = a { 
    // works fine 
} 

लेकिन यह कैसे मैं विपरीत स्थिति की जांच कि मैं कैसे की जाँच करेगा है? (a बराबर .B)? यहाँ मैं क्या करने की कोशिश की है:

if case .B != a { // Variable binding in a condition requires an initializer 
    // ... 
} 

if !(case .B = a) { // Expected ',' separator 
    // ... 
} 
बेशक

, मैं इसे इस तरह से कर सकता है:

if case .B = a { 
    // ... 
} else { 
    // put your code here 
} 

लेकिन यह अजीब है, साथ ही switch कथन का उपयोग है। क्या कोई बेहतर विकल्प हैं?


संपादित करें: समाधान @Greg काम करता है का सुझाव दिया है, तो मामलों मूल्यों संबद्ध कर दिया है नहीं है, लेकिन == ऑपरेटर अतिभारित होने की जरूरत है अगर वे करते हैं। इसे पहली जगह में स्पष्ट करने के लिए खेद है।

+0

अगर! (मामला बी = ए) {// अपेक्षित ',' विभाजक। - यह डबल == एकल नहीं होना चाहिए। – Greg

+0

@ ग्रेग, नोप, एक ही त्रुटि –

उत्तर

6

आप एकल = चिह्न का उपयोग कर रहे हैं जो एक असाइनमेंट ऑपरेटर है। आप जो एक तुलना एक है डबल == उपयोग करने के लिए है और मामले का उपयोग नहीं करते ए, का उपयोग ईए कि करने के लिए सही तरीका है:

if E.A == a { 
    // works fine 
    print("1111") 
} 

if E.B != a { 
    // works fine 
    print("2222") 
} 

if E.B == a { 
    // works fine 
    print("3333") 
} 

विस्तारित:

यह संबद्ध के साथ काम करता बनाने के महत्व देता है आप Equatable प्रोटोकॉल को लागू करने के लिए है, उदाहरण के लिए:

extension E: Equatable {} 
func ==(lhs: E, rhs: E) -> Bool { 
    switch (lhs, rhs) { 
     case (let .C(x1), let .C(x2)): 
      return x1 == x2 
     case (.A, .A): 
     return true 

    default: 
     return false 
    } 
} 
बेशक आप संभावनाओं के सभी संभाल करने के लिए है के

लेकिन मुझे लगता है कि आप एक विचार है।

विस्तारित:

मैं अपनी टिप्पणी नहीं मिलता है, लेकिन यह मेरे लिए ठीक काम करता है:

enum E { 
    case A, B, C(Int) 
} 

extension E: Equatable {} 
func ==(lhs: E, rhs: E) -> Bool { 
    switch (lhs, rhs) { 
     case (let .C(x1), let .C(x2)): 
      return x1 == x2 
     case (.A, .A): 
      return true 
     case (.B, .B): 
      return true 

    default: 
     return false 
    } 
} 

let a: E = .A 
let b: E = .B 
let c: E = .C(11) 

if E.A == a { 
    // works fine 
    print("aaa true") 
} 
if E.A != a { 
    // works fine 
    print("aaa false") 
} 

if E.B == b { 
    // works fine 
    print("bbb true") 
} 

if E.B == b { 
    // works fine 
    print("bbb false") 
} 

if E.C(11) == c { 
    // works fine 
    print("ccc true") 
} 

if E.C(11) != c { 
    // works fine 
    print("1 ccc false") 
} 

if E.C(22) != c { 
    // works fine 
    print("2 ccc false") 
} 
+3

सच है, यह काम करता है, लेकिन यदि मामलों के मूल्यों से जुड़े नहीं हैं। इस पर क्लियरफिंग के लिए खेद है। –

+0

@deville विस्तृत उत्तर देखें। – Greg

+1

अगर मैं '==' अधिभार करता हूं तो यह 'ए' और' बी' के लिए काम करेगा, लेकिन 'सी' के लिए नहीं, जो संबंधित मूल्य है। यही कारण है कि पैटर्न मिलान की जरूरत है। –

14

यह "जवाब" एक अधिक कॉम्पैक्ट तरीके से अपने अजीब समाधान लिखने की तुलना में ज्यादा कुछ नहीं है । आप केवल मामले के बारे में परवाह है, जब एक मूल्य एक निश्चित enum मूल्य का नहीं है, आप इसे तुरंत खाली तो खंड निम्नलिखित else के साथ इस सब में एक पंक्ति लिख सकते हैं:

enum E { 
    case A, B(String), C(Int) 
} 

let a: E = .B("Hello") 

if case .A = a {} else { 
    print("not an A") 
} 

if case .B = a {} else { 
    print("not a B") 
} 

if case .C = a {} else { 
    print("not a C") 
} 
+1

कोई भी जो इस कोड को पढ़ता है, वह '{} else' भाग को नोटिस नहीं कर सकता है, लेकिन हाँ, अन्यथा यह एक व्यवहार्य समाधान है :) –

+0

@AndriiChernenko स्विफ्ट के' गार्ड' कीवर्ड _requires_ 'else' के उपयोग को ध्यान में रखते हुए, मुझे लगता है कि यह हो सकता है औसत स्विफ्ट प्रोग्रामर द्वारा grokkable हो। –

3

वहाँ नहीं किसी भी कर रहे हैं उत्तर अभी तक guard कथन का उल्लेख करते हैं, जो स्विफ्ट 2 द्वारा पेश किया गया है, जो ऊपर दिए गए टूल्स के लिए एक साफ जोड़ है और यदि आप मुझसे पूछते हैं, तो सबसे साफ समाधान अगर आप को else -block में अपने फ़ंक्शन या बंद से आवश्यकता के साथ जी सकते हैं :

guard case .B = a else { 
    // a does not match .B 
    return 
} 

मोर के लिए Apple's "The Swift Programming Language (Swift 2.2): Statements" देखें ई जानकारी।

+8

यदि यह वास्तव में एक अमान्य मामला है तो गार्ड स्वीकार्य है। हालांकि अगर यह कुछ कार्यक्षमता गार्ड को निष्पादित करने के प्रवाह का सिर्फ एक हिस्सा है तो मुझे लगता है कि यहां गलत जगह होगी। तुम क्या सोचते हो? – Starceaker

+1

यदि आप गार्ड क्लॉज "गिरने" का प्रयास करते हैं तो स्विफ्ट कंपाइलर आपको चिल्लाएगा: 'गार्ड' बॉडी हो सकता है, 'वापसी' या 'ब्रेक' का उपयोग करने के लिए दायरे से बाहर निकलने पर विचार करें। मुझे लगता है कि "गार्डिंग" "अमान्य" से कम नकारात्मक लगता है, जो, यदि आप उन्हें तटस्थ परिप्रेक्ष्य से संपर्क करते हैं, तो आप केवल विनाश को रोकने की तुलना में बहुत अधिक मामलों के लिए 'गार्ड'-क्लॉज का उपयोग करने की अनुमति दे सकते हैं :) – epologee

+0

यह जानना अच्छा है कि संकलक गार्ड क्लॉज (गिरने) के दुरुपयोग को रोकता है। मेरी परियोजना अभी भी इसके बच्चे के चरणों में है और मैंने केवल उन परिस्थितियों को पकड़ने के लिए गार्ड का उपयोग किया है जिन्हें मैं अनुमति नहीं देता हूं। धन्यवाद। – Starceaker

0

.case कथन को नकारात्मक करना संभव नहीं है।हालांकि आप सामान्य तुलना का उपयोग कर सकते हैं, जैसे:

if a != .B { 

} 

यह मेरी राय में लिखने का सबसे सीधा तरीका है।

+0

दुर्भाग्यवश, यह केवल तभी काम करता है जब 'बी' में संबंधित मान नहीं हैं। –

+0

आह, मैं देखता हूं। माफ़ कीजिये :( –

संबंधित मुद्दे