Swift 2 添加协议一致性协议
Swift 2 add protocol conformance to protocols
我可以通过 swift 扩展将协议一致性添加到协议吗?
//Plain old protocol here
protocol MyData {
var myDataID: Int { get }
}
我想使 MyData
协议默认相等(只需比较 ID)
extension MyData : Equatable { }
但是我得到了这个可爱的错误:
"Extension of protocol 'MyData' cannot have an inheritance clause"
我正在寻找的行为是符合 Equatable(协议)的 BananaData,因为它实现了 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
}
正如错误信息所说:协议的扩展不能有继承子句。相反,您可以使 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
的 ==
变得多余。
这个游乐场符合您的要求吗?我是根据我从 WWDC 2015 Protocol-Oriented Programming in Swift 了解到的内容制作的。
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
我可以通过 swift 扩展将协议一致性添加到协议吗?
//Plain old protocol here
protocol MyData {
var myDataID: Int { get }
}
我想使 MyData
协议默认相等(只需比较 ID)
extension MyData : Equatable { }
但是我得到了这个可爱的错误:
"Extension of protocol 'MyData' cannot have an inheritance clause"
我正在寻找的行为是符合 Equatable(协议)的 BananaData,因为它实现了 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
}
正如错误信息所说:协议的扩展不能有继承子句。相反,您可以使 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
的 ==
变得多余。
这个游乐场符合您的要求吗?我是根据我从 WWDC 2015 Protocol-Oriented Programming in Swift 了解到的内容制作的。
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