斯威夫特“哪里"数组扩展 [英] Swift "where" Array Extensions

查看:16
本文介绍了斯威夫特“哪里"数组扩展的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 Swift 2.0 开始,我们似乎可以更接近适用于谓词情况的泛型类型的扩展.

As of Swift 2.0 it seems we can get closer to extensions of generic types applicable to predicated situations.

虽然我们还是做不到:

protocol Idable {
    var id : String { get }
}

extension Array where T : Idable {
    ...
}

...我们现在可以这样做:

...we can now do this:

extension Array {
    func filterWithId<T where T : Idable>(id : String) -> [T] {
    ...
    }
}

...Swift 在语法上接受了它.但是,对于我来说,当我填写示例函数的内容时,我无法弄清楚如何让编译器满意.假设我要尽可能明确:

...and Swift grammatically accepts it. However, for the life of me I cannot figure out how to make the compiler happy when I fill in the contents of the example function. Suppose I were to be as explicit as possible:

extension Array {
    func filterWithId<T where T : Idable>(id : String) -> [T] {
        return self.filter { (item : T) -> Bool in
            return item.id == id
        }
    }
}

...编译器不会接受提供给过滤器的闭包,抱怨

...the compiler will not accept the closure provided to filter, complaining

无法使用类型为 '((T) -> Bool)' 的参数列表调用 'filter'

Cannot invoke 'filter' with an argument list of type '((T) -> Bool)'

如果 item 被指定为 Idable,则类似.这里有人有运气吗?

Similar if item is specified as Idable. Anyone had any luck here?

推荐答案

extension Array {
    func filterWithId<T where T : Idable>(id : String) -> [T] {
    ...
    }
}

定义一个泛型方法 filterWithId() 其中泛型占位符 T 被限制为 Idable.但该定义引入了本地占位符 T与数组元素类型 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).

所以你没有指定数组元素必须符合Idable,这就是你不能调用的原因self.filter() { ... } 带有一个需要元素的闭包成为Idable.

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.

从 Swift 2/Xcode 7 beta 2 开始,您可以在泛型类型上定义扩展方法,这对模板有更多限制(比较数组扩展以按值删除对象 非常相似的问题):

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
        }
    }
}

然后 filterWithId() 可用于所有符合到 SequenceType(特别是 Array)如果序列元素类型符合Idable.

Then filterWithId() is available to all types conforming to SequenceType (in particular to Array) if the sequence element type conforms to 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
        }
    }
}

这篇关于斯威夫特“哪里"数组扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆