Swift 协议强制 Equatable 协议

Swift protocol forcing the Equatable protocol

我定义了2个协议。 我需要第一个 (NameProtocol) 来执行 Equatable 协议。 而另一个 class (BuilderProtocol) 有一个方法 return 第一个 (NameProtocol)。

public protocol NameProtocol : Equatable {
    var name: String { get }
}

public protocol BuilderProtocol {
    func build() -> NameProtocol? // Compiler error
    init()
}

编译器错误: "Protocol 'NameProtocol' can only be used as a generic constraint because it has Self or associated type requirements"

我需要对象 return 通过 build() 到 return 一个符合 NameProtocol 的对象,我可以在其上定义 ==

有什么方法可以使它工作吗?

谢谢


如果在 BuilderProtocol 中使用类型别名,我怎样才能使数组声明起作用?

public protocol OtherRelatedProtocol {
    var allNames : Array<NameProtocol> { get }
}

结论

我将删除 Equatable 并实现一个 isEqual 方法。

public protocol NameProtocol {
    func isEqual(nameable: NameProtocol) -> Bool
    var name: String { get }
}

如果您熟悉 Java 或 C#,Swift 协议大约介于泛型和接口之间。例如,您可以在协议中做的一件事是:

protocol Foo {
    func compareWith(foo: Self)
}
实现此协议的

类 将有一个方法 compareWith 接受对象 自己的类型 (而不是类型 Foo).

这就是编译器调用的 "Self or associated type requirements",这就是 Equatable 的定义方式(它需要一个接受两个 Self 操作数的 operator==)。但是,这些协议的缺点是您只能将它们用作通用约束:不能将它们用作表达式类型。

解决方案是使用泛型。在这种情况下,您可以使 ProtocolBuilder 协议通用,并限制该类型实现 NameProtocol.

public protocol NameProtocol : Equatable {
    var name: String { get }
}

public protocol BuilderProtocol {
    typealias T: NameProtocol
    func build() -> T?
    init()
}