I have define 2 protocols. I need the first one (NameProtocol) to enforce the Equatable protocol. While the other class (BuilderProtocol) have a method that return the first one (NameProtocol).
public protocol NameProtocol : Equatable {
var name: String { get }
}
public protocol BuilderProtocol {
func build() -> NameProtocol? // Compiler error
init()
}
The compiler error : "Protocol 'NameProtocol' can only be used as a generic constraint because it has Self or associated type requirements"
I need the object return by build() to return an object conforming to the NameProtocol and on which I can define ==
Is there a way I can make this work?
Thanks
If using a typealias in BuilderProtocol how can I make the array declaration work?
public protocol OtherRelatedProtocol {
var allNames : Array<NameProtocol> { get }
}
Conclusion
I will remove the Equatable and implement an isEqual method.
public protocol NameProtocol {
func isEqual(nameable: NameProtocol) -> Bool
var name: String { get }
}
If you're familiar with Java or C#, Swift protocols are about halfway between generics and interfaces. One thing that you can do in a protocol, for instance, is this:
protocol Foo {
func compareWith(foo: Self)
}
Classes that implement this protocol will have a method compareWith
that accept an object of their own type (and not an object of type Foo
).
This is what the compiler calls "Self or associated type requirements", and this is how Equatable is defined (it needs an operator==
that accepts two Self
operands). The downside of these protocols, though, is that you can only use them as generic constrains: you can't use them as an expression type.
The solution is to use generics. In this case, you'd make your ProtocolBuilder
protocol generic, with a constraint that the type implements NameProtocol
.
public protocol NameProtocol : Equatable {
var name: String { get }
}
public protocol BuilderProtocol {
typealias T: NameProtocol
func build() -> T?
init()
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加