从Swift 2.0开始,我们似乎可以更接近适用于预测情况的通用类型的扩展。
虽然我们还是不能这样做:
protocol Idable { var id : String { get } } extension Array where T : Idable { ... }
…我们现在可以这样做:
extension Array { func filterWithId<T where T : Idable>(id : String) -> [T] { ... } }
…和Swift语法接受。然而,对于我的生活我无法弄清楚当我填写示例函数的内容时如何使编译器快乐。假设我是尽可能明确的:
extension Array { func filterWithId<T where T : Idable>(id : String) -> [T] { return self.filter { (item : T) -> Bool in return item.id == id } } }
…编译器不会接受提供的关闭来过滤,抱怨
Cannot invoke ‘filter’ with an argument list of type ‘((T) -> Bool)’
类似,如果项目被指定为空闲。任何人都有运气吗
extension Array { func filterWithId<T where T : Idable>(id : String) -> [T] { ... } }
定义一个通用方法filterWithId(),其中通用
占位符T被限制为无效。但该定义引入了本地占位符T
这与数组元素类型T完全无关
(并隐藏在该方法的范围内)。
所以你没有指定数组元素必须符合
为了自动,这就是为什么你不能打电话的原因
self.filter(){…}带有一个封闭,期望元素
要自给自足
从Swift 2 / Xcode 7 beta 2开始,您可以在通用类型上定义扩展方法,对模板更加限制
(比较Array extension to remove object by value为非常类似的问题):
extension Array where Element : Idable { func filterWithId(id : String) -> [Element] { return self.filter { (item) -> Bool in return item.id == id } } }
或者,您可以定义协议扩展方法:
extension SequenceType where Generator.Element : Idable { func filterWithId(id : String) -> [Generator.Element] { return self.filter { (item) -> Bool in return item.id == id } } }
那么filterWithId()可用于所有符合的类型
到SequenceType(特别是Array)如果是序列元素
类型符合Idable。
在Swift 3这将是
extension Sequence where Iterator.Element : Idable { func filterWithId(id : String) -> [Iterator.Element] { return self.filter { (item) -> Bool in return item.id == id } } }