Swift协议强制Equatable协议

时间:2015-04-24 03:35:12

标签: swift swift-protocols

我已经定义了2个协议。 我需要第一个(NameProtocol)来强制执行Equatable协议。 而另一个类(BuilderProtocol)有一个方法返回第一个(NameProtocol)。

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

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

编译错误: “协议'NameProtocol'只能用作通用约束,因为它具有Self或相关类型要求”

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

我有办法让这项工作成功吗?

由于

如果在BuilderProtocol中使用typealias,我该如何使数组声明工作?

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

结论

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

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

1 个答案:

答案 0 :(得分:3)

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

protocol Foo {
    func compareWith(foo: Self)
}

实现此协议的类将有一个方法compareWith接受自己类型的对象 (而不是Foo类型的对象。)

这是编译器调用“Self或关联类型要求”的内容,这就是Equatable的定义方式(它需要operator==接受两个Self操作数)。但是,这些协议的缺点是您只能将它们用作通用约束:您不能将它们用作表达式类型。

解决方案是使用泛型。在这种情况下,您将使ProtocolBuilder协议具有通用性,并使用类型实现NameProtocol的约束。

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

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