4

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

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

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

编译器错误:“Protocol '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 }
}
4

1 回答 1

3

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

protocol Foo {
    func compareWith(foo: Self)
}

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

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

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

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

public protocol BuilderProtocol {
    typealias T: NameProtocol
    func build() -> T?
    init()
}
于 2015-04-24T03:51:29.310 回答