我想擴展Array以增加對新協議的一致性-但僅適用于其元素本身符合特定協議的數組。更籠統地說,我想讓帶有類型參數的類型(無論是協議類型還是具體類型)僅在類型參數與某些約束匹配時才實現協議。從Swift 2.0開始,這似乎是不可能的。有什么我想念的方式嗎?例假設我們有以下Friendly協議:protocol Friendly { func sayHi()}我們可以擴展現有的類型來實現它:extension String: Friendly { func sayHi() { print("Greetings from \(self)!") }}"Sally".sayHi()我們還可以擴展Array實現sayHi()所有元素Friendly:extension Array where Element: Friendly { func sayHi() { for elem in self { elem.sayHi() } }}["Sally", "Fred"].sayHi()此時,類型[Friendly]本身應該實現Friendly,因為它滿足協議的要求。但是,此代碼無法編譯:extension Array: Friendly where Element: Friendly { func sayHi() { for elem in self { elem.sayHi() } }}錯誤消息是“具有約束的'Array'類型的擴展不能具有繼承子句”,這似乎最終確定了直接方法的大門。有間接解決方法嗎?我可以使用一些巧妙的技巧?也許有一種方法涉及擴展SequenceType而不是Array?一個有效的解決方案將使此代碼編譯:let friendly: Friendly = ["Foo", "Bar"]更新:它已落入Swift 4.1中,真是太美了!extension Array: Friendly where Element: Friendly現在,該示例將按照原始問題中的說明進行編譯。
2 回答

白豬掌柜的
TA貢獻1893條經驗 獲得超10個贊
編輯:如更新的問題中所述,自Swift 4.1起,現在可以實現
目前在Swift中(從Xcode 7.1開始)無法實現。如錯誤所示,您不能將協議一致性(“繼承子句”)限制為類型受限的擴展。也許有一天。我不認為沒有任何可能的深層原因,但是目前尚未實現。
您可以獲得的最接近的結果是創建一個包裝器類型,例如:
struct FriendlyArray<Element: Friendly>: Friendly {
let array: [Element]
init(_ array: [Element]) {
self.array = array
}
func sayHi() {
for elem in array {
elem.sayHi()
}
}
}
let friendly: Friendly = FriendlyArray(["Foo", "Bar"])
(您可能想擴展FriendlyArray為一個CollectionType。)
有關我自己陷入嘗試進行這項工作的瘋狂以及我從邊緣爬回的故事,請參閱NSData,我的老朋友。
- 2 回答
- 0 關注
- 614 瀏覽
添加回答
舉報
0/150
提交
取消