young
(rtSwift)
1
Write this func as closure:
func isMatch<Element>(_ a: Element, _ b: Element) -> Bool where Element: Equatable {
a == b
}
into something like this:
let isMatch = { (_ a: Element, _ b: Element) -> Bool in a == b }
How to constraint Element to be Equatable?
So the answer is no-can-do: ios - is it possible to create a generic closure in Swift? - Stack Overflow
But typealiase can have generic.
1 Like
mbrandonw
(Brandon Williams)
2
Closures can't have generics, but you can erase the elements to Any and then open them back up to Equatable:
let isEqual: (Any, Any) -> Bool = { lhs, rhs in
guard
let lhs = lhs as? any Equatable,
let rhs = rhs as? any Equatable
else { return false }
return open(lhs, rhs)
func open<T: Equatable>(_ lhs: T, _ rhs: Any) -> Bool {
lhs == (rhs as? T)
}
}
isEqual(1, 1) // true
isEqual("hello", "goodbye") // false
isEqual(1, "goodbye") // false
The only thing you lose is the guarantee that both lhs and rhs are the same type, and there are some edge cases around subclasses when opening existentials like this. Oh and I guess there is technically a performance hit, but probably only noticeable if invoked many, many times.
2 Likes
jrose
(Jordan Rose)
3
The other (heavyweight) choice is to use a protocol with the generic function as its single requirement, and implement a new local type every time you want a different implementation. Which is possible, but a lot more trouble than a closure, at least today. Maybe a macro?
2 Likes