我想让我的协议符合 Equatable。但是,每当我使用该协议时,我都会收到错误Type any {protocol} does not conform to Equatable.
protocol ExampleDataProtocol: Equatable {
var someData: Int { get set }
}
public extension ExampleDataProtocol {
static func ==(lhs: any ExampleDataProtocol, rhs: any ExampleDataProtocol) -> Bool {
return lhs.someData == rhs.someData
}
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.someData == rhs.someData
}
}
struct SomeStruct: Equatable { // Type 'SomeStruct' does not conform to protocol 'Equatable'
var someData: any ExampleDataProtocol
}
Run Code Online (Sandbox Code Playgroud)
当我手动添加协议存根时,我any ExampleDataProtocol 对 Equatable 感到不舒服。
struct SomeStruct: Equatable {
static func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
lhs.someData == rhs.someData // Type 'any ExampleDataProtocol' cannot conform to 'Equatable'
}
var someVar: any ExampleDataProtocol
}
Run Code Online (Sandbox Code Playgroud)
协议不符合协议。他们可能需要其他协议,但他们不遵守这些协议。DataProtocol 不是 Equatable。它要求符合类型是 Equatable。
存在主义any DataProtocol也不符合等值律。存在性从不遵守协议,但在这种情况下,Equatable 要求它的两个参数具有完全相同的类型(Self),而不是“符合此协议的东西”。您的扩展提供了一个==函数,但它没有Equatable所需的签名:
static func == (lhs: Self, rhs: Self) -> Bool
Run Code Online (Sandbox Code Playgroud)
注意这里的自我。这与 不是一回事any DataProtocol。该扩展将方法附加到符合类型。存在(any)包装了一个符合 DataProtocol 的值,但它本身并不符合 DataProtocol。(有一天我预计any类型可能符合某些协议,但它们可能永远无法符合具有 Self 要求或静态方法的协议,而 Equatable 两者都有。)
您可以这样实现您所描述的内容:
extension DataProtocol {
// This compares `self` to any other DataProtocol, not just Self.
func isEqual(to other: some DataProtocol) -> Bool {
return data == other.data
}
}
struct SomeStruct {
var someData: any DataProtocol
}
extension SomeStruct: Equatable {
static func == (lhs: SomeStruct, rhs: SomeStruct) -> Bool {
lhs.someData.isEqual(to: rhs.someData)
}
}
Run Code Online (Sandbox Code Playgroud)