簡體   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