As of Swift 2.0 it seems we can get closer to extensions of generic types applicable to predicated situations.
Although we still can\'t do this:
pro
extension Array {
func filterWithId<T where T : Idable>(id : String) -> [T] {
...
}
}
defines a generic method filterWithId()
where the generic
placeholder T
is restricted to be Idable
. But that definition introduces a local placeholder T
which is completely unrelated to the array element type T
(and hides that in the scope of the method).
So you have not specified that the array elements must conform
to Idable
, and that is the reason why you cannot call
self.filter() { ... }
with a closure which expects the elements
to be Idable
.
As of Swift 2 / Xcode 7 beta 2, you can define extension methods on a generic type which are more restrictive on the template (compare Array extension to remove object by value for a very similar issue):
extension Array where Element : Idable {
func filterWithId(id : String) -> [Element] {
return self.filter { (item) -> Bool in
return item.id == id
}
}
}
Alternatively, you can define a protocol extension method:
extension SequenceType where Generator.Element : Idable {
func filterWithId(id : String) -> [Generator.Element] {
return self.filter { (item) -> Bool in
return item.id == id
}
}
}
Then filterWithId()
is available to all types conforming
to SequenceType
(in particular to Array
) if the sequence element
type conforms to Idable
.
In Swift 3 this would be
extension Sequence where Iterator.Element : Idable {
func filterWithId(id : String) -> [Iterator.Element] {
return self.filter { (item) -> Bool in
return item.id == id
}
}
}