Swift 2 добавить протокол к протоколам
Могу ли я добавить соответствие протокола протоколу через быстрое расширение?
//Plain old protocol here
protocol MyData {
var myDataID: Int { get }
}
Я хочу сделать MyData
протокол равным по умолчанию (просто сравните ID)
extension MyData : Equatable { }
Но я получаю эту прекрасную ошибку:
"Расширение протокола" MyData "не может иметь условие наследования"
Поведение, которое я ищу, - это BananaData, соответствующая Equatable (протокол), поскольку он реализует протокол MyData, который может обеспечить стандартную реализацию Equatable
//This is the method to implement Equatable
func ==(lhs: MyData, rhs: MyData) -> Bool {
return lhs.myDataID == rhs.myDataID
}
struct BananaData: MyData {
var myDataID: Int = 1
}
func checkEquatable(bananaOne: BananaData, bananaTwo: BananaData) {
//This compiles, verifying that BananaData can be compared
if bananaOne == bananaTwo { }
//But BananaData is not convertible to Equatable, which is what I want
let equatableBanana = bananaOne as Equatable
//I don't get the additional operations added to Equatable (!=)
if bananaOne != bananaTwo { } //Error
}
Ответы
Ответ 1
Как говорится в сообщении об ошибке: расширение протокола не может иметь условие наследования. Вместо этого вы можете сделать наследование MyData
наследовать от Equatable
в исходной декларации.
protocol MyData: Equatable {
var myDataID: Int { get }
}
Затем вы можете расширить добавление реализации ==
для типов, соответствующих MyData
:
func == <T: MyData>(lhs: T, rhs: T) -> Bool {
return lhs.myDataID == rhs.myDataID
}
Однако я бы не рекомендовал этого! Если вы добавите больше свойств в соответствующие типы, их свойства не будут проверяться на равенство. Пример:
struct SomeData: MyData {
var myDataID: Int
var myOtherData: String
}
let b1 = SomeData(myDataID: 1, myOtherData: "String1")
let b2 = SomeData(myDataID: 1, myOtherData: "String2")
b1 == b2 // true, although `myOtherData` properties aren't equal.
В приведенном выше случае вам нужно переопределить ==
для SomeData
для правильного результата, тем самым сделав ==
, который принимает MyData
избыточность.
Ответ 2
Разве эта игровая площадка делает то, что вы хотите? Я сделал это на основе того, что я понимаю из Протокольно-ориентированное программирование в Swift из WWDC 2015.
import Foundation
//Plain old protocol here
func == (lhs: MyData, rhs: MyData) -> Bool {
return lhs.myDataID == rhs.myDataID
}
func != (lhs: MyData, rhs: MyData) -> Bool {
return lhs.myDataID != rhs.myDataID
}
protocol MyData {
var myDataID: Int { get }
}
extension MyData where Self: Equatable {
}
struct BananaData: MyData {
var myDataID: Int = 1
}
func checkEquatable(bananaOne: BananaData, bananaTwo: BananaData) {
//This compiles, verifying that BananaData can be compared
if bananaOne == bananaTwo {
print("Same")
}
//But BananaData is not convertible to Equatable, which is what I want
//I don't get the additional operations added to Equatable (!=)
print(bananaOne.myDataID)
print(bananaTwo.myDataID)
if bananaOne != bananaTwo {
}
//Error
}
let b1 = BananaData(myDataID: 2)
let b2 = BananaData(myDataID: 2)
checkEquatable(b1, bananaTwo: b2)
let c = b1 == b2 // Evaluates as true