繁体   English   中英

面向Swift协议的扩展

[英]Swift Protocol Oriented Extensions

试图让我了解Swift中面向协议的编程,以及扩展的工作方式以及它可以提供的扩展级别。

具有我在Playgrounds中运行过的以下代码段

protocol ProtocolA {
    func doSomethingA()
}

protocol ProtocolB {
    func doSomethingB()
}

protocol ProtocolC {
    func doSomethingC()
}

extension ProtocolA {
    func doSomethingA() {
        print("Extension - doSomethingA")
    }
}

extension ProtocolA where Self: ProtocolB {
    func doSomethingA() {
        print("Extension - doSomethingA Self: ProtocolB")
    }
}

extension ProtocolA where Self: ProtocolC {
    func doSomethingA() {
        print("Extension - doSomethingA Self: ProtocolC")
    }
}

extension ProtocolA where Self: ProtocolB, Self: ProtocolC {
    func doSomethingA() {
        print("Extension - doSomethingA Self: ProtocolB, ProtocolC")
    }
}

extension ProtocolB {
    func doSomethingB() {
        print("Extension - doSomethingB")
    }
}

extension ProtocolC {
    func doSomethingC() {
        print("Extension - doSomethingC")
    }
}

class Implementation: ProtocolA, ProtocolB, ProtocolC {
}

let obj = Implementation()

obj.doSomethingA()

我得到的是:

Extension - doSomethingA Self: ProtocolB, ProtocolC

无论如何,我可以保证所有扩展都能运行。

理想情况下,我想获得以下输出。

Extension - doSomethingA
Extension - doSomethingA Self: ProtocolB
Extension - doSomethingA Self: ProtocolC
Extension - doSomethingA Self: ProtocolB, ProtocolC

我确实知道Swift会根据类型选择最强的匹配,实际上,如果我不提供ProtocolA匹配ProtocolB和ProtocolC的实现,则会出现编译时错误。 无论如何,我可以解决这个问题吗?

谢谢。

扩展点是为协议方法提供默认实现

在您的示例中,编译器将解析为调用最适合您的具体对象的扩展名的doSomethingA()方法,仅此而已。

正如您在呼叫点所看到的:

obj.doSomethingA()

您正在执行一种方法调用。 这将解决并分配给一个方法调用,而不是四个。

这类似于通过子类重写方法并调用基类的方法时,仅调用派生的方法,而不调用基类的方法。 在这种情况下,如果需要,可以从子类中调用super.method()

对于您的情况,如果要调用多个方法,则可以通过扩展为它们指定单独的名称和实现,然后只需创建一个类即可实现所有协议,如下所示:

class A: ProtocolA, ProtocolB, ProtocolC {

   func all() {
      doSomethingA()
      doSomethingB()
      doSomethingC()
   }
}

这里扩展的优点是您的class A不必为这三种方法提供实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM