Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 2将协议一致性添加到协议中_Swift_Protocols_Swift2 - Fatal编程技术网

Swift 2将协议一致性添加到协议中

Swift 2将协议一致性添加到协议中,swift,protocols,swift2,Swift,Protocols,Swift2,我可以通过swift扩展向协议添加协议一致性吗 //Plain old protocol here protocol MyData { var myDataID: Int { get } } 我想使MyData协议在默认情况下是相等的(只需比较ID) 但我有一个可爱的错误: “协议'MyData'的扩展不能有继承子句” 我所关注的行为是BananaData符合Equatable(协议),因为它实现了MyData协议,该协议可以提供Equatable的默认实现 //This is the

我可以通过swift扩展向协议添加协议一致性吗

//Plain old protocol here
protocol MyData {
    var myDataID: Int { get }
}
我想使
MyData
协议在默认情况下是相等的(只需比较ID)

但我有一个可爱的错误:

“协议'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
}

正如错误消息所说:协议的扩展不能有继承子句。相反,您可以使
MyData
协议继承原始声明中的
equalable

protocol MyData: Equatable {
    var myDataID: Int { get }
}
然后,您可以为符合
MyData
的类型扩展并添加
=
的实现:

func == <T: MyData>(lhs: T, rhs: T) -> Bool {
    return lhs.myDataID == rhs.myDataID
}

在上述情况下,您需要为
SomeData
覆盖
==
,以获得正确的结果,从而使接受
MyData
=
变得多余。

这个游乐场能满足您的需要吗?我是根据2015年世界野生动植物保护大会(WWDC)上我所了解的情况制作的

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

接下来,我假设无论谁实现了
MyData
,都必须显式地实现equalable。实现equalable是MyData的一项要求(这是我想要避免的)。
BananaData
显然是一个有贡献的示例,但感谢您的警告。如果结构属性符合equalable(使用
=
),您将自动获得函数
=。我正在使用
=
检查
BananaData
是否确实符合
equalable
协议,而不仅仅是使用
=
方法。因此,在为我的测试用例编译时,我真正寻找的是为所有
MyData
structs.Hi@Kevin实现
equalable
的方法。我不知道这是否有区别,但我看到当你这样做的时候你会出错
extensionmydata:Equatable{}
但是当您执行像这样的受约束协议扩展
extensionmydata其中Self:Equatable{}
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.
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