2015-04-07 8 views
6

मैं 2 तर्कों के साथ तेजी से कक्षा के लिए एक विधि बना रहा हूं, और वे दोनों वैकल्पिक हैं। हालांकि, मैं उनमें से कम से कम एक विधि सफलतापूर्वक काम करने के लिए के लिए भर जाने की जरूरत है, यह कोई बात नहीं जो एकस्विफ्ट वैकल्पिक विधि तर्क लेकिन कम से कम एक को पॉप्युलेट किया जाना चाहिए

func someMethod(arg1: Sometype?, arg2: Sometype?)-> Void { 
     //I need at least one argument to 
     //be populated to do what i need 
} 

ऑब्जेक्टिव-सी में हम एक जोर फेंक सकता है अगर इन वस्तु के दोनों शून्य था। स्विफ्ट में मैं "सोच अगर वहाँ एक ज़ोर से यह करने के लिए एक बेहतर तरीका है हूँ

उत्तर

4

मैं एयरस्पेड वेग से सहमत हूं कि आपको यहां अधिभार का उपयोग करना चाहिए, लेकिन मैं उन्हें अलग-अलग बना दूंगा। विकल्पों को पूरी तरह से छुटकारा पाएं।

func someMethod(#arg1: Sometype)-> Void {} 

func someMethod(#arg2: Sometype)-> Void {} 

func someMethod(#arg1: Sometype, #arg2: Sometype) -> Void {} 

जो बिंदु पर, यह स्पष्ट है कि इन वास्तव में अलग अलग तरीके हैं होना चाहिए:

func someMethodWithArg1(arg1: Sometype)-> Void {} 

func someMethodWithArg2(arg2: Sometype)-> Void {} 

func someMethod(#arg1: Sometype, #arg2: Sometype) -> Void {} 

इस ठोस बनाने के लिए, पर विचार अगर हम एक FixedLengthString वर्ग है कि आप एक लंबाई करने के लिए दे सकते हैं बना रहे थे, या एक मौजूदा स्ट्रिंग, या आप दोनों पास कर सकते हैं और यह लंबाई भरने तक स्ट्रिंग दोहराएगा।

आप का वर्णन होगा क्या कर रहे हैं:

func makeString(length: Int?, string: String?) -> FixedString 

बल्कि उसके अलावा, बस तरीकों बनाने:

func makeStringWithLength(length: Int) -> FixedString 
func makeStringFromString(string: String) -> FixedString 
func makeStringByFillingWith(string: String, totalLength: Int) -> FixedString 

यह यह स्पष्ट कैसे सब कुछ काम करता है बनाता है, और आप कॉल नहीं कर सकते यह गलत है। ओबीजेसी में आपको यह भी करना चाहिए।

+0

दूंगा, मुझे लगता है कि यह सबसे अधिक समझ में आता है और स्पष्ट मंजूरी देता है, धन्यवाद – bolnad

2

आप के बजाय अधिक भार का उपयोग कर सकता:।

// arg1 cannot be nil 
func someMethod(arg1: Int, arg2: Int?)-> Void { 
    println("arg2 was nil") 
    somePrivateMethod(arg1,arg2) 
} 

// arg2 cannot be nil 
func someMethod(arg1: Int?, arg2: Int)-> Void { 
    println("arg1 was nil") 
    somePrivateMethod(arg1,arg2) 
} 

// this version is needed to avoid annoying "ambiguous call" 
// errors when passing two non-optionals in... 
func someMethod(arg1: Int, arg2: Int)-> Void { 
    println("neither was nil") 
    somePrivateMethod(arg1,arg2) 
} 

private func somePrivateMethod(arg1: Int?, arg2: Int?)-> Void { 
    // private method in which at least arg1 or arg2 will be guaranteed non-nil 
} 


someMethod(1, nil) // prints "arg2 was nil" 
someMethod(nil, 1) // prints "arg1 was nil" 
someMethod(1, 1) // prints "neither was nil" 

// but if you try this: 
someMethod(nil, nil) // error: cannot find an overload for 'someMethod' 
         // that accepts an argument list of type '(nil, nil)' 

इस का नकारात्मक पहलू है कि फोन करने वाले तर्कों को खोलने के लिए मजबूर किया जाता है - वे जांच के बिना दो विकल्प नहीं पारित कर सकते हैं कि उनमें से कोई भी शून्य न हो। लेकिन यह एक विशेषता है, बग नहीं! इसका मतलब है कि कॉलर के लिए गलती से एपीआई को कॉल करने के लिए शारीरिक रूप से असंभव है "गलत रास्ता "और एक अनुमान उत्पन्न करें।

बेशक, इससे सवाल उठता है कि वास्तव में आप कई ओवरलोड लेना चाहते हैं जो अलग-अलग संख्या लेते हैं तर्क या विभिन्न प्रकार के बर्स (रॉब का जवाब देखें), जो आपके उपयोग के संदर्भ के संदर्भ में विचार करने योग्य भी है।

+0

उन तरीकों पर जहां एक तर्क की आवश्यकता होती है, क्या यह होना चाहिए! कुछ विधि (arg1: Int !, arg2: int?), कुछ विधि (arg1: में ?, arg2: Int!) – bolnad

+1

बहुत निश्चित रूप से नहीं। एक 'इंट!' सिर्फ एक 'इंट' है जो कि जब आप इसका इस्तेमाल करते हैं तो "निस्संदेह" अनचाहे होता है। यदि आपने 'func someMethod लिखा है (arg1: int !, arg2: int?) -> शून्य' तो आप इसे 'someMethod (nil, nil)' के रूप में कॉल कर सकते हैं, टाइप-आधारित प्रवर्तन को हराकर कम से कम एक गैर-शून्य है। –

+0

ओह ठीक स्पष्टीकरण के लिए धन्यवाद, मैं इसे एक शॉट – bolnad

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