2015-09-16 7 views
47

मुझे आश्चर्य है कि ऐसी चीज हासिल करना संभव है या नहीं।नियमित विधि से कॉलिंग प्रोटोकॉल डिफ़ॉल्ट कार्यान्वयन

protocol Foo { 
    func testPrint() 
} 

extension Foo { 
    func testPrint() { 
     print("Protocol extension call") 
    } 
} 

struct Bar: Foo { 
    func testPrint() { 
     // Calling self or super go call default implementation 
     self.testPrint() 
     print("Call from struct") 
    } 
} 


let sth = Bar() 
sth.testPrint() 

मैं extension में एक डिफ़ॉल्ट कार्यान्वयन प्रदान कर सकते हैं, लेकिन क्या हुआ अगर Bar सब कुछ डिफ़ॉल्ट कार्यान्वयन के साथ साथ अतिरिक्त बातों में है कि जरूरत:
मैं इस तरह एक खेल का मैदान है?
यह किसी भी तरह super. विधियों को class es में प्रत्येक संपत्ति को लागू करने की आवश्यकता को पूरा करने के लिए कॉल करने जैसा है। लेकिन मुझे structs के साथ इसे प्राप्त करने की कोई संभावना नहीं है।

+0

मैं का प्रयोग करेंगे 'Foo.testPrint (स्वयं)()' - समस्या यह है कि यह एक विभाजन के कारण विफल रहता है गलती (7.0 जीएम और 7.1 बीटा दोनों पर परीक्षण) – Antonio

+0

यह एक अजीब construc है टियर आपने – cojoj

+2

प्रस्तुत किया है प्रत्येक इंस्टेंस विधि एक स्थिर घुमावदार विधि है जिसका उदाहरण पहला पैरामीटर – Antonio

उत्तर

54

मैं अगर आप अभी भी यह करने के लिए एक जवाब के लिए देख रहे हैं पता नहीं है, लेकिन जिस तरह से यह करने के लिए प्रोटोकॉल परिभाषा से समारोह को दूर करने के लिए है, Foo करने के लिए अपने वस्तु डाली और फिर विधि कॉल यह:

protocol Foo { 
    // func testPrint() <- comment this out or remove it 
} 

extension Foo { 
    func testPrint() { 
     print("Protocol extension call") 
    } 
} 

struct Bar: Foo { 
    func testPrint() { 
     print("Call from struct") 
     (self as Foo).testPrint() // <- cast to Foo and you'll get the default 
            // function defined in the extension 
    } 
} 

Bar().testPrint() 

// Output: "Call from struct" 
//   "Protocol extension call" 

किसी कारण यह तभी काम करता है समारोह प्रोटोकॉल के हिस्से के रूप में घोषित किया नहीं है, लेकिन प्रोटोकॉल के लिए एक विस्तार में परिभाषित किया गया है के लिए। जाओ पता लगाओ। लेकिन यह काम करता है।

+0

हां मुझे कुछ ब्लॉग पोस्ट पर यह समाधान मिला, जो कि रास्ते से बहुत अच्छा था ... – cojoj

+0

हे भगवान! मुझे विश्वास नहीं है कि वे आपको प्रोटोकॉल से बाहर निकलने के लिए मजबूर करते हैं! अच्छा जवाब, धन्यवाद! –

+2

यह मेरे लिए एक बग जैसा दिखता है, यह एक ही उदाहरण कास्टिंग करके विभिन्न विधि कार्यान्वयन प्राप्त करना संभव नहीं होना चाहिए। –

5

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

struct Bar: Foo { 
    func testPrint() { 
     // Calling default implementation 
     struct Dummy : Foo {} 
     let dummy = Dummy() 
     dummy.testPrint() 
     print("Call from struct") 
    } 
} 
+1

ऐसा लगता है कि यह अभी एकमात्र संभावना है (ऐप्पल द्वारा पुष्टि की गई) ... मैं इस के लिए एक फीचर रडार फाइल करूंगा क्योंकि यह उपयोगी हो सकता है – cojoj

1

पोस्ट के लिए धन्यवाद! यदि आप प्रोटोकॉल में फ़ंक्शन परिभाषा डालते हैं तो जब ऑब्जेक्ट को प्रोटोकॉल के रूप में डाला जाता है तो यह केवल कार्य के ऑब्जेक्ट के संस्करण को देखता है और चूंकि आप इसे अपने अंदर कॉल कर रहे हैं तो आपको ऐप्पल का नया पता मिल जाएगा ...

I

import UIKit 
protocol MyProc 
{ 
} 

protocol MyFuncProc 
{ 
    func myFunc() 
} 

extension MyProc 
{ 
    func myFunc() 
    { 
     print("Extension Version") 
    } 
} 

struct MyStruct: MyProc, MyFuncProc 
{ 
    func myFunc() 
    { 
     print("Structure Version") 
     (self as MyProc).myFunc() 
    } 
} 

(MyStruct() as MyFuncProc).myFunc() 

इस के उत्पादन देता है: इस तरह एक संस्करण की कोशिश किया था

Structure Version 
Extension Version 
संबंधित मुद्दे