2017-12-18 129 views
5

मैं अपने एपीआई को कंक्रीट क्वेरी ऑब्जेक्ट्स को एक पैरामीटर के रूप में लेने के लिए डिजाइन कर रहा हूं, क्योंकि सभी जगहों के हस्ताक्षरों को विस्फोट करने के विपरीत पैरामीटर पारित किए जा सकते हैं।क्या आप पैरामीटर पास करने के लिए structs के लिए स्विफ्ट के डिफ़ॉल्ट प्रारंभकर्ता का लाभ उठा सकते हैं?

उदाहरण के लिए, बल्कि यह लिखने की तुलना में

...

func someQuery(requiredA:Bool, requiredB:Int, requiredC:String, defaultedA:Bool = false, defaultedB:Int = 1, defaultedC:String = "X", optionalA:Bool? = nil, optionalB:Int? = nil, optionalC:String? = nil){ 
    .... 
} 

मैं इस लिख रहा हूँ ...

func someQuery(queryParams:QueryParams){ 
    .... 
} 

और मैं परिभाषित करने कर रहा हूँ (आंशिक रूप से - नीचे और अधिक) क्वेरी इस तरह की वस्तु ...;

struct QueryObject{ 
    let requiredA : Bool 
    let requiredB : Int 
    let requiredC : String 
    let defaultedA : Bool 
    let defaultedB : Int 
    let defaultedC : String 
    let optionalA : Bool? 
    let optionalB : Int? 
    let optionalC : String? 
} 

के रूप में मुझे यकीन है कि आप नाम से बता सकते हैं, इस उदाहरण के लिए, कुछ आवश्यक हैं हूँ, कुछ चूक है और कुछ पूरी तरह से वैकल्पिक हैं।

अब क्वेरीपैरम्स ऑब्जेक्ट को परिभाषित करने के लिए, मैं इसे बनाने के दौरान इसे बनाने की कोशिश कर रहा हूं, उपयोगकर्ता को केवल आवश्यक पैरामीटर निर्दिष्ट करना होगा, और वैकल्पिक रूप से दूसरों को निर्दिष्ट/फिट करने के लिए वैकल्पिक रूप से निर्दिष्ट कर सकते हैं।

यहाँ क्या मैं के बाद हूँ ...

// At a minimum 
let queryParams = QueryParams(requiredA:true, requiredB:1, requiredC:"x") 

// Minimums overriding a default 
let queryParams = QueryParams(requiredA:true, requiredB:1, requiredC:"x", defaultC:"y") 

// Minimums plus an optional, still picking up all defaults 
let queryParams = QueryParams(requiredA:true, requiredB:1, requiredC:"x", optionalB:8) 

इस लक्ष्य को हासिल करने के लिए, मैं अपने खुद के प्रारंभकर्ता कि कुछ नहीं करता है, लेकिन आंतरिक मानकों प्रदान करती है, तो जैसे ... बनाया है

struct QueryParams{ 

    init(
     requiredA : Bool, 
     requiredB : Int, 
     requiredC : String, 
     defaultedA : Bool = true, 
     defaultedB : Int  = 1, 
     defaultedC : String = "x", 
     optionalA : Bool? = nil, 
     optionalB : Int? = nil, 
     optionalC : String? = nil 
    ){ 
     self.requiredA = requiredA 
     self.requiredB = requiredB 
     self.requiredC = requiredC 
     self.defaultedA = defaultedA 
     self.defaultedB = defaultedB 
     self.defaultedC = defaultedC 
     self.optionalA = optionalA 
     self.optionalB = optionalB 
     self.optionalC = optionalC 
    } 

    let requiredA : Bool 
    let requiredB : Int 
    let requiredC : String 
    let defaultedA : Bool 
    let defaultedB : Int 
    let defaultedC : String 
    let optionalA : Bool? 
    let optionalB : Int? 
    let optionalC : String? 
} 

... जो बॉयलरप्लेट कोड के बहुत सारे जैसा लगता है। मैं यह पता लगाने की कोशिश कर रहा हूं कि स्विफ्ट के एक स्ट्रक्चर के डिफ़ॉल्ट प्रारंभकर्ता के निर्माण का लाभ उठाने का कोई तरीका है, इसलिए मुझे इसे मैन्युअल रूप से लिखना नहीं है।

ध्यान दें

:

  1. मैं structs यहाँ का चयन कर रहा हूँ क्योंकि स्विफ्ट उन्हें कक्षा जबकि एक डिफ़ॉल्ट initializers देता AFAIK कि नहीं मिलता है।
  2. जाहिर है, आवश्यक पैरामीटर पहले आना होगा। इसके अलावा, इससे कोई फर्क नहीं पड़ता (हालांकि यह ठीक है अगर उन्हें परिभाषा-आदेश में भी होना चाहिए। प्वाइंट मुझे परवाह नहीं है।)
  3. सदस्य चर let या var हो सकते हैं। मैं बस आदत के रूप में let का उपयोग करता हूं।

तो ... क्या यह कोड सरलीकृत/कम/समाप्त हो सकता है?

+1

संपादित। इस तरह की चीजों के लिए ऐसा करने के लिए स्वतंत्र महसूस करें। यही तो मैं करता हूं। – MarqueIV

उत्तर

0

आप इस तरह के नियंत्रण को डिफ़ॉल्ट प्रारंभकर्ता से स्वयं प्राप्त नहीं कर पा रहे हैं। कम से कम कोड के संदर्भ में, मैं इस तरह कुछ सुझाऊंगा।

struct QueryParams{ 

    let requiredA : Bool 
    let requiredB : Int 
    let requiredC : String 
    var defaultedA : Bool = true 
    var defaultedB : Int = 1 
    var defaultedC : String = "x" 
    var optionalA : Bool? = nil 
    var optionalB : Int? = nil 
    var optionalC : String? = nil 
} 

extension QueryParams { 
    init(
     requiredA : Bool, 
     requiredB : Int, 
     requiredC : String 
     ){ 
     self.requiredA = requiredA 
     self.requiredB = requiredB 
     self.requiredC = requiredC 
    } 
} 

अपने कस्टम प्रारंभकर्ता को एक एक्सटेंशन में डालकर, आप डिफ़ॉल्ट प्रारंभकर्ता को मुफ्त में रखते हैं। एकमात्र समस्या यह है कि अगर वे केवल कुछ गैर-आवश्यक गुणों को अनुकूलित करना चाहते हैं, जिन्हें प्रारंभ करने के बाद उन्हें करना होगा।

+0

सच है, लेकिन डिफ़ॉल्ट प्रारंभकर्ता को रखने में क्या बिंदु है यदि यह आपको सब कुछ निर्दिष्ट करने के लिए मजबूर करता है? और यदि आपको वैसे भी एक प्रारंभकर्ता लिखना है, तो आप डिफ़ॉल्ट रूप से सभी मामलों को संभालने के लिए इसे बाहर कर सकते हैं, और यदि आप ऐसा करते हैं, तो फिर भी डिफ़ॉल्ट प्रारंभकर्ता की आवश्यकता नहीं है।इसके अलावा, पूर्ण-प्रारंभिक प्रारंभकर्ता का अन्य लाभ सब कुछ एक लेट में बनाया जा सकता है। मैं बस उम्मीद कर रहा था कि इसे स्वचालित रूप से करने का कोई तरीका था, लेकिन मुझे लगता है कि ऐसा नहीं है। – MarqueIV

+0

आपके अंक मान्य हैं। मेरी राय में, आपको जो भी कर रहा था उसके साथ जाना चाहिए, भले ही यह बहुत सारे बॉयलरप्लेट की तरह दिखता हो। आप जो खोज रहे थे उसके आधार पर कम से कम कोड के साथ सबसे अधिक लचीलापन प्राप्त करने का यह एक तरीका है। दुर्भाग्य से, आप जो खोज रहे हैं वह उपलब्ध नहीं है। यह बहुत खराब है कि यह डिफ़ॉल्ट मानों का पता नहीं लगा सकता है और तदनुसार डिफ़ॉल्ट प्रारंभकर्ता समायोजित कर सकता है। – JustinM

+0

पूरी तरह से सहमत हैं। हमेशा स्विफ्ट 5 है! :) एक बार फिर धन्यवाद! – MarqueIV

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