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
有没有什么我可以 gua运行tee 运行.
的所有扩展
理想情况下,我希望获得以下输出。
Extension - doSomethingA
Extension - doSomethingA Self: ProtocolB
Extension - doSomethingA Self: ProtocolC
Extension - doSomethingA Self: ProtocolB, ProtocolC
我明白 Swift 会根据类型选择最强的匹配,事实上,如果我不提供 ProtocolA 与 ProtocolB 和 ProtocolC 都匹配的实现,我会得到一个编译时间错误。无论如何,我可以解决这个问题吗?
谢谢。
扩展点是为协议方法提供默认实现。
在您的示例中,编译器将决定调用最适合您的具体对象的扩展的 doSomethingA()
方法,仅此而已。
正如您在通话中看到的那样:
obj.doSomethingA()
您正在执行一个方法调用。这将被解析并分派给一个方法调用,而不是四个。
这类似于通过 subclassing 覆盖方法并调用基 class 的方法时,仅调用派生方法而不调用基 class一。在那种情况下,如果你愿意,你可以从 subclass.
调用 super.method()
在您的情况下,如果您希望调用多个方法,您可以通过扩展为它们提供单独的名称和实现,然后只需创建一个实现所有协议的 class,如下所示:
class A: ProtocolA, ProtocolB, ProtocolC {
func all() {
doSomethingA()
doSomethingB()
doSomethingC()
}
}
此处扩展的优点是您的 class A
不必为这三种方法提供实现。
试图了解 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
有没有什么我可以 gua运行tee 运行.
的所有扩展理想情况下,我希望获得以下输出。
Extension - doSomethingA
Extension - doSomethingA Self: ProtocolB
Extension - doSomethingA Self: ProtocolC
Extension - doSomethingA Self: ProtocolB, ProtocolC
我明白 Swift 会根据类型选择最强的匹配,事实上,如果我不提供 ProtocolA 与 ProtocolB 和 ProtocolC 都匹配的实现,我会得到一个编译时间错误。无论如何,我可以解决这个问题吗?
谢谢。
扩展点是为协议方法提供默认实现。
在您的示例中,编译器将决定调用最适合您的具体对象的扩展的 doSomethingA()
方法,仅此而已。
正如您在通话中看到的那样:
obj.doSomethingA()
您正在执行一个方法调用。这将被解析并分派给一个方法调用,而不是四个。
这类似于通过 subclassing 覆盖方法并调用基 class 的方法时,仅调用派生方法而不调用基 class一。在那种情况下,如果你愿意,你可以从 subclass.
调用super.method()
在您的情况下,如果您希望调用多个方法,您可以通过扩展为它们提供单独的名称和实现,然后只需创建一个实现所有协议的 class,如下所示:
class A: ProtocolA, ProtocolB, ProtocolC {
func all() {
doSomethingA()
doSomethingB()
doSomethingC()
}
}
此处扩展的优点是您的 class A
不必为这三种方法提供实现。