I have a protocol, that has a typealias:
protocol Fooable {
typealias T: Equatable
func makeFoo() -> T
}
I expect, that all types, that conforms to it will return Equatable values from makeFoo
.
Now I'd like to make an array extension, which stores Fooable
values:
extension Array where Element: Fooable {
func arrayFoo<F: Foobable, S>(array: Array<F>, transform: (Element, [F]) -> S) -> [S] {
I expect, that given array A, which contains Fooable
elements and array B, which contains Fooable
elements I can make:
a.arrayFoo(b, {...})
I have a part of arrayFoo
function:
var leftGenerator = self.generate()
var rightGenerator = array.generate()
if let leftValue = leftGenerator.next(), rightValue = rightGenerator.next() {
let leftFoo = leftValue.makeFoo()
let rightFoo = rightValue.makeFoo()
if leftFoo == rightFoo {
I expect leftFoo
and rightFoo
to be Equatable, because they are produced by makeFoo()
, which should return Equatables.
But Swift complains: Binary operator == cannot be applied to operands of type Element.T and FT
Any ideas or workarounds?
In your arrayFoo()
method, both array
and self
are arrays of Fooable
elements, but not necessarily with the same underlying type T
, ie Element.T
and FT
are unrelated types.
You can fix that with an additional constraint where FT == Element.T
on the type placeholders:
func arrayFoo<F: Fooable, S where F.T == Element.T >(array: Array<F>, transform: (Element, [F]) -> S) -> [S] {
// ...
}
I think that problem is inside Equatable
protocol, look in it's declaration:
@warn_unused_result
public func ==(lhs: Self, rhs: Self) -> Bool
You should override func ==
and provide some result for this, or Swift
compiler doesn't know, hot to compare it. You use generic type, it's not settled how to compare Int
and String
for example
let t = 0
let a = "string"
if t == a { // error
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.