यदि तार्किक और ऑपरेटर के साथ स्विफ्ट का उपयोग करें &&


93

हम जानते हैं कि हम if letवैकल्पिक शून्य की जांच के लिए शॉर्टहैंड के रूप में एक कथन का उपयोग कर सकते हैं ।

हालाँकि, मैं तार्किक और ऑपरेटर का उपयोग करके एक और अभिव्यक्ति के साथ संयोजन करना चाहता हूं &&

इसलिए, उदाहरण के लिए, यहां मैं अनप्लग करने के लिए वैकल्पिक चाइनिंग करता हूं और वैकल्पिक रूप से अपने रूटव्यूकंट्रोलर को टैबबेरकंट्रोलर में डाउनकास्ट करता हूं। लेकिन बयानों के बजाय नेस्टेड होने के बावजूद, मैं उन्हें संयोजित करना चाहूंगा।

if let tabBarController = window!.rootViewController as? UITabBarController {
    if tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
 }

संयुक्त दे:

if let tabBarController = window!.rootViewController as? UITabBarController &&
    tabBarController.viewControllers.count > 0 {
        println("do stuff")
     }
}

उपरोक्त संकलन त्रुटि देता है अनसुलझे पहचानकर्ता का उपयोग 'tabBarController'

सरल बनाना:

if let tabBarController = window!.rootViewController as? UITabBarController && true {
   println("do stuff")
}

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

तो, सवाल यह है कि क्या यह संभव है और यदि ऐसा है तो सही वाक्यविन्यास क्या है?

ध्यान दें कि मैं एक ifबयान के साथ यह करना चाहता हूं न कि एक switchबयान या एक टर्नरी ?ऑपरेटर।


प्रश्न में त्रुटि संदेश प्रदान करना हमेशा एक अच्छा विचार है।
ज़ैफ़

ऐसे लोगों के लिए अधिक सरल कथन जो इसके साथ प्रयोग करना पसंद करते हैं:var foo : Int? = 10; if let bar = foo { if bar == 10 { println("Great success!") }}
DarkDust

का उपयोग करते समय त्रुटि संदेश if let bar = foo && bar == 10है Use of unresolved identifier "bar"(दूसरी पर barज़ाहिर है,)।
डार्कडस्ट

सिर्फ एक नोट कि मैं उपरोक्त उदाहरण को Objective C के FirstObject के रूप में निम्न प्रकार से सक्षम कर सकता हूं: यदि नेविगेशन को कंट्रोलर = tabBarController.viewControllers.bridgeToObjectiveC ()। FirstObject के रूप में बताएं। UINavigationController {
मैक्स मैकलॉड

1
1. bridgeToObjectiveCबीटा 5 में चला गया है (और संभवतः सामान्य उपयोग के लिए कभी संभव नहीं था)। 2. firstस्विफ्ट के बिल्ट-इन Arrayप्रकार पर एक विधि है।
रिकस्टर

जवाबों:


143

स्विफ्ट 1.2 के रूप में, यह अब संभव हैस्विफ्ट 1.2 और Xcode 6.3 बीटा रिलीज नोट्स राज्य:

यदि जाने दें तो अधिक शक्तिशाली वैकल्पिक आवरण - यदि निर्माण अब एक ही बार में कई वैकल्पिकों को खोल सकता है, साथ ही साथ बूलियन स्थितियों में हस्तक्षेप भी कर सकता है। यह आपको अनावश्यक घोंसले के बिना सशर्त नियंत्रण प्रवाह व्यक्त करने देता है।

उपरोक्त कथन के साथ, वाक्य रचना तब होगी:

if let tabBarController = window!.rootViewController as? UITabBarController where tabBarController.viewControllers.count > 0 {
        println("do stuff")
}

यह whereक्लॉज का उपयोग करता है ।

एक और उदाहरण, इस बार कास्टिंग AnyObjectको Intअल्टरनेटिव करना, और यह जांचना कि अलिखित वैकल्पिक शर्त पूरी करती है:

if let w = width as? Int where w < 500
{
    println("success!")
}

अब स्विफ्ट 3 का उपयोग करने वालों के लिए, "जहां" को अल्पविराम द्वारा बदल दिया गया है। इसलिए समतुल्य होगा:

if let w = width as? Int, w < 500
{
    println("success!")
}

2
यह चुना हुआ जवाब आना चाहिए।
फ्रांसिस.बियुखामप जुआन

हाँ, अब यह बदल गया है। उस समय ब्रायन का जवाब सही था
मैक्स मैकलॉड

58

में स्विफ्ट 3 मैक्स मेक्लेओड के उदाहरण इस प्रकार दिखाई देगा:

if let tabBarController = window!.rootViewController as? UITabBarController, tabBarController.viewControllers.count > 0 {
    println("do stuff")
}

whereने उनकी जगह ली,


10
तो, && के लिए क्या है || ?
jeet.chanchawat

9
@ jeet.chanchawat तार्किक या इस संदर्भ में कोई मतलब नहीं है। if letकेवल तभी आगे बढ़ सकते हैं जब वैकल्पिक सफलतापूर्वक अलिखित हो और नए चर नाम को सौंपा गया हो। अगर आपने कहा OR <something else>तो आप आसानी से पूरे उद्देश्य को दरकिनार कर सकते हैं if let। तार्किक OR के लिए, बस एक सामान्य करें ifऔर शरीर के अंदर इस तथ्य से निपटें कि पहली वस्तु अभी भी उस बिंदु पर वैकल्पिक है (अलिखित नहीं)।
झब्बोट

37

मैक्स का जवाब सही है और ऐसा करने का एक तरीका है। इस तरह से लिखे जाने पर ध्यान दें:

if let a = someOptional where someBool { }

someOptionalअभिव्यक्ति पहले का समाधान हो जाएगा। यदि यह विफल रहता है, तो someBoolअभिव्यक्ति का मूल्यांकन नहीं किया जाएगा (शॉर्ट-सर्किट मूल्यांकन, जैसा कि आप उम्मीद करेंगे)।

यदि आप इसे अन्य तरीके से लिखना चाहते हैं तो ऐसा किया जा सकता है:

if someBool, let a = someOptional { }

इस मामले someBoolमें पहले मूल्यांकन किया जाता है, और केवल अगर यह सच का मूल्यांकन करता है तो someOptionalअभिव्यक्ति का मूल्यांकन किया जाता है।


5

स्विफ्ट 4 , मैं उपयोग करूंगा,

let i = navigationController?.viewControllers.index(of: self)
if let index = i, index > 0, let parent = navigationController?.viewControllers[index-1] {
    // access parent
}

4

यह संभव नहीं है।

से स्विफ्ट व्याकरण

यदि कोई स्थिति का विवरण

if-statement → यदि इफ़-कंडीशन कोड-ब्लॉक-क्लॉज़ॉप्ट

if-condition → अभिव्यक्ति | घोषणा

बाकी-खंड → किसी और कोड-ब्लॉक | और अगर बयान

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

if-condition अभिव्यक्ति या घोषणा होनी चाहिए । आपके पास अभिव्यक्ति और घोषणा दोनों नहीं हो सकते।

let foo = barएक घोषणा है, यह उस मूल्य का मूल्यांकन नहीं करता है जिसके अनुरूप है BooleanType। यह एक स्थिर / परिवर्तनशील घोषित करता है foo

आपका मूल समाधान काफी अच्छा है, यह बहुत अधिक पठनीय है और फिर स्थितियों का संयोजन।


लेकिन निश्चित रूप से "अगर चलो" - जो वैध है स्विफ्ट सिंटैक्स - एक अभिव्यक्ति और एक घोषणा दोनों है?
मैक्स मैकलेओड

@MaxMacLeod let foo = barअभिव्यक्ति नहीं है। तुम नहीं कर सकतेlet boolValue = (let foo = bar)
ब्रायन चेन

ठीक है, लेकिन स्विफ्ट गाइड, पेज 11 को उद्धृत करने के लिए, उदाहरण है: यदि नाम = वैकल्पिक नाम। वैकल्पिकनाम एक अभिव्यक्ति होना चाहिए जिससे अगर वैकल्पिक नाम वैकल्पिक नहीं है, तो यह सत्य का मूल्यांकन करता है। कथन का दूसरा भाग तब किक करता है जिसमें अलिखित वैकल्पिक को नाम दिया गया है। तो, सवाल यह है कि अगर "ऑप्शनल नेम ऑप्शनल नहीं है" एक एक्सप्रेशन है, तो क्या इसे लॉजिकल एंड के साथ बढ़ाया जा सकता है। Btw मुझे लगता है कि आप शायद सही हैं कि यह नहीं किया जा सकता है।
मैक्स मैकलॉड

-1

मुझे लगता है कि आपका मूल प्रस्ताव बहुत बुरा नहीं है। ए (मेसियर) विकल्प होगा:

if ((window!.rootViewController as? UITabBarController)?.viewControllers.count ?? 0) > 0 {
    println("do stuff")
}

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