2015-09-16 31 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