2015-07-29 27 views
5

मैं प्रोटोकॉल को लागू करने वाले सामान्य प्रकारों का एक कारखाना बनाने की कोशिश कर रहा हूं। समस्या यह है कि make एडाप्टर फैक्ट्री की विधि में मुझे निम्न त्रुटि मिलती है: Protocol 'Adapter' can only be used as a generic constraint because it has Self or associated type requirementsस्विफ्ट (प्रोटोकॉल और जेनेरिक) में सामान्य प्रकार की फैक्टरी

यहाँ अब मैं क्या कर रहा हूँ का एक उदाहरण है:

protocol Adapter { 

    typealias T 

    static func method1(parameter: T) 
} 

final class AdapterFactory<T>: NSObject { 

    static func make(name: String = "") -> Adapter.Type { 

     switch name { 

     case "Adapter1": 
      return ConcreteAdapter1<T>.self 

     default: 
      return ConcreteAdapter2<T>.self 
     } 

    } 
} 

final class ConcreteAdapter1<T>: NSObject, Adapter { 

    static func method1(parameter: T) { 
     // bla, bla, bla 
    } 
} 

उत्तर

2

आप तेजी से मानक पुस्तकालय में इस्तेमाल एक पैटर्न का उपयोग AnyAdapter की तरह कुछ है कि द्वारा एडाप्टर प्रोटोकॉल लागू करता है का उपयोग कर यानी (अनुक्रम और AnySequence देखें) कर सकते हैं अंतर्निहित कार्यान्वयन (कंक्रीटएडाप्टर 1 जैसे एडाप्टर प्रोटोकॉल का ठोस कार्यान्वयन) या बंद करने का उपयोग करके प्रत्येक विधि कॉल को प्रतिनिधि देना।

आपका कारखाना एडाप्टर के बजाय AnyAdapter वापस करेगा। यह पहली बार अप्राकृतिक प्रतीत हो सकता है लेकिन किसी भी एडाप्टर का उपयोग करने के रूप में प्रोटोकॉल का उपयोग करने के समान प्रकार देता है (जाहिर है यह एक वर्कअराउंड है) क्योंकि AnyAdapter स्वयं द्वारा एक ठोस कार्यान्वयन नहीं है बल्कि यह कार्यान्वयन को ठोस कार्यान्वयन के लिए प्रस्तुत करता है।

यहाँ कोड

protocol Adapter { 

    typealias Element 

    func method1(parameter: Element) 

    func method2(parameter : Element) 
} 




struct AnyAdapter<Element> : Adapter { 

    private let _method1 : (Element) ->() 

    private let _method2 : (Element) ->() 


    init<A:Adapter where A.Element == Element>(_ base:A) { 
     _method1 = { base.method1($0) } 
     _method2 = { base.method2($0) } 
    } 

    func method1(parameter: Element) { 
     _method1(parameter) 
    } 

    func method2(parameter: Element) { 
     _method2(parameter) 
    } 

} 



final class ConcreteAdapter1<T>: NSObject, Adapter { 

    func method1(parameter: T) { 
     print("Concrete Adapter 1 method 1") 
    } 

    func method2(parameter: T) { 
     print("Concrete Adapter 1 method 2") 
    } 
} 



final class ConcreteAdapter2<T> : Adapter { 
    func method1(parameter: T) { 
     print("Concrete adapter 2 method 1") 
    } 

    func method2(parameter: T) { 
     print("Concrete Adapter 2 method 2") 
    } 
} 

final class AdapterFactory<T>: NSObject { 

    static func make(name: String = "") -> AnyAdapter<String> { 

     switch name { 


     case "Adapter1": 
      let concreteAdapter1 = ConcreteAdapter1<String>() 
      return AnyAdapter(concreteAdapter1) 

     default: 
      let concreteAdapter2 = ConcreteAdapter2<String>() 
      return AnyAdapter(concreteAdapter2) 
     } 

    } 
} 

मैं प्रोटोकॉल में एक स्थिर विधि का उपयोग नहीं कर रहा हूँ बातें सरल स्टैटिक्स सामान्य प्रकार के साथ अच्छी तरह से काम नहीं करते के बाद से बनाने के लिए है।

ईमानदार होने के लिए यह भाषा में एक कमी है और मैं चाहता हूं कि यह जावा या सी # जैसे सरल होने के लिए इस चीज़ की तरह काम करे।

उम्मीद है कि इससे मदद मिलती है।

+0

यह समझना मुश्किल है ... अगर मेरे प्रोटोकॉल में अन्य विधियां थीं, तो मैं उन्हें कैसे कॉल करूं? – OscarVGG

+0

किसी अन्य ठोस कार्यान्वयन के संदर्भ में AnyAdapter को लागू करने का एक बेहतर तरीका मिला। मेरी पोस्ट अपडेट करने जा रहे हैं। यहां मैं प्रोटोकॉल में परिभाषित दो तरीकों को लागू कर रहा हूं। मुझे बताएं कि आप क्या सोचते हैं – salman140

+0

वाह, यह काम करता है, लेकिन यह निश्चित रूप से कुछ आसान करने के लिए बहुत जुगलिंग है जो सरल होना चाहिए। मुझे उम्मीद है कि ऐप्पल इसे ठीक करेगा। धन्यवाद! :) – OscarVGG

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