我已经定义了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 }
}
答案 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()
}