स्विफ्ट में एक वैकल्पिक क्लोजर कैसे बनता है?


93

मैं स्विफ्ट में एक तर्क घोषित करने की कोशिश कर रहा हूं जो एक वैकल्पिक क्लोजर लेता है। मैंने जो फ़ंक्शन घोषित किया है वह इस तरह दिखता है:

class Promise {

 func then(onFulfilled: ()->(), onReject: ()->()?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

}

लेकिन स्विफ्ट की शिकायत है कि "सशर्त में बाउंड वैल्यू एक वैकल्पिक प्रकार होना चाहिए" जहां "अगर" जाने दिया जाए।


मापदंडों के साथ केवल एक बंद का उपयोग करने पर विचार करें।
कैटालोर

जवाबों:


113

आपको कोष्ठक में वैकल्पिक बंद को शामिल करना चाहिए। यह ?ऑपरेटर को ठीक से स्कोप देगा ।

func then(onFulfilled: ()->(), onReject: (()->())?){       
    if let callableRjector = onReject {
      // do stuff! 
    }
 }

क्या आप जानते हैं कि कोष्ठक में संलग्न करने के लिए औचित्य क्या है?
मार्कोस

5
शायद अस्पष्टता को दूर करने के लिए। यदि वैकल्पिक क्लोजर का रिटर्न वैल्यू होता है, तो ()->Int?इसका मतलब क्या हो सकता है।
सेज़ार

3
इसके अलावा, स्विफ्ट पुस्तक से: “वैकल्पिक प्रकार की घोषणा करते समय, सुनिश्चित करने के लिए कि कोष्ठक का सही तरीके से उपयोग करना सुनिश्चित करें? ऑपरेटर। एक उदाहरण के रूप में, पूर्णांकों की वैकल्पिक सारणी घोषित करने के लिए, टाइप एनोटेशन को लिखें (Int []) ;; Int [] लेखन? एक त्रुटि पैदा करता है। ”
सेज़ार

@Cezar क्या आप थोड़ा समझा सकते हैं कि "वैकल्पिक समापन" का उपयोग क्यों और कहाँ करना है, मैं यह जानने के लिए उत्सुक हूं।
लोरियर

@Cezar इस समय मैक पर नहीं है इसलिए मेरा सिंटैक्स थोड़ा बंद हो सकता है, लेकिन याद रखें कि ?यह वास्तव में सिर्फ चीनी है Optional<T>, इसलिए आप `फ़िनिश '(ऑनफ़ुल्फल्ड: () -> (), ऑनरेज़: ऑप्शनल <() भी लिख सकते हैं। -> ()>) {`तब आपको अतिरिक्त की जरूरत नहीं होगी (), हालांकि IMO ()?प्रीटियर है। इसके अलावा आप इसे टाइपेलियास के साथ भी बना सकते हैं जैसेtypealias RejectHandler = () -> () func then(onFulfilled: ()->(), onReject: RejectHandler?) {
एंड्रयू कार्टर

62

कोड को और भी छोटा बनाने के लिए हम इसे कॉल करते समय पैरामीटर और वैकल्पिक चेनिंग के nilलिए डिफ़ॉल्ट मान के रूप में उपयोग कर सकते हैं :onReject?()

func then(onFulfilled: ()->(), onReject: (()->())? = nil) {
  onReject?()
}

इस तरह हम फंक्शन को onRejectकॉल करने पर पैरामीटर को छोड़ सकते हैं then

then({ /* on fulfilled */ })

हम फंक्शन onRejectमें पैरामीटर पास करने के लिए ट्रेलिंग क्लोजर सिंटैक्स का भी उपयोग कर सकते हैं then:

then({ /* on fulfilled */ }) {
  // ... on reject
}

यहाँ इसके बारे में एक ब्लॉग पोस्ट है।


34

चूंकि मैं मानता हूं, कि इस "वैकल्पिक" क्लोजर को बस कुछ नहीं करना चाहिए, आप डिफ़ॉल्ट मान के रूप में एक खाली क्लोजर के साथ एक पैरामीटर का उपयोग कर सकते हैं:

func then(onFulfilled: ()->(), onReject: ()->() = {}){       
    // now you can call your closures
    onFulfilled()
    onReject()
}

इस फ़ंक्शन को अब onRejectकॉलबैक के साथ या बिना कॉल किया जा सकता है

then({ ... })
then({ ... }, onReject: { ... })

Optionals?यहां स्विफ्ट के कमाल की जरूरत नहीं !


यह अच्छा उपाय है!
रोलैंड टी।

6

शायद यह एक क्लीनर तरीका है। विशेष रूप से जब क्लोजर में जटिल पैरामीटर होते हैं।

typealias SimpleCallBack = () -> ()

class Promise {

func then(onFulfilled: SimpleCallBack, onReject: SimpleCallBack?){       
    if let callableRjector = onReject {
        // do stuff! 
    }
}

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