2015-09-16 57 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 GM和7.1 beta上測試) – Antonio

+0

這是一個奇怪的構造你已經提出 – cojoj

+2

每個實例方法是一個靜態的curried方法,以一個實例作爲其第一個參數 – 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

哦,上帝!我無法相信他們強迫你從協議中拿出func!很好的答案,謝謝! –

+2

這對我來說看起來像是一個bug,不應該通過只投射相同的實例來獲得不同的方法實現。 –

5

那麼,你可以創建一個符合協議的嵌套類型,實例化它,然後調用該方法(無論如何,由於協議擴展內部的實現無法引用它,無法訪問類型的數據並不重要)。但這不是我稱之爲優雅的解決方案。

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

看起來這是目前唯一的可能性(由Apple確認) ...我會爲這個文件提供一個特徵雷達,因爲它可能是有用的 – cojoj

1

感謝帖子!如果您將函數定義放入協議中,那麼當對象作爲協議被轉換時,它只會看到對象的函數版本,並且由於您在其內部調用它,您將得到Apple的新地址...

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