Swift "where" 数组扩展
Swift "where" Array Extensions
从 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
被限制为 Idable
。但是这个定义引入了一个本地占位符 T
这与数组元素类型完全无关 T
(并将其隐藏在方法的范围内)。
所以你没有指定数组元素必须符合
到 Idable
,这就是你不能调用的原因
self.filter() { ... }
带有一个需要元素的闭包
成为 Idable
.
从 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
}
}
}
从 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
被限制为 Idable
。但是这个定义引入了一个本地占位符 T
这与数组元素类型完全无关 T
(并将其隐藏在方法的范围内)。
所以你没有指定数组元素必须符合
到 Idable
,这就是你不能调用的原因
self.filter() { ... }
带有一个需要元素的闭包
成为 Idable
.
从 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
}
}
}