如果Element符合给定协议,则扩展阵列以符合协议

时间:2015-10-19 16:22:48

标签: ios swift protocols protocol-extension

我想做类似的事情,但无法正确使用语法或在网络上的任何地方找到正确的方法来编写语法:

protocol JSONDecodeable {
    static func withJSON(json: NSDictionary) -> Self?
}

protocol JSONCollectionElement: JSONDecodeable {
    static var key: String { get }
}

extension Array: JSONDecodeable where Element: JSONCollectionElement {
    static func withJSON(json: NSDictionary) -> Array? {
        var array: [Element]?
        if let elementJSON = json[Element.key] as? [NSDictionary] {
            array = [Element]()
            for dict in elementJSON {
                if let element = Element.withJSON(dict) {
                    array?.append(element)
                }
            }
        }
        return array
    }
}

所以,只有当此数组的元素符合Array时,我才希望JSONDecodeable符合我的协议JSONCollectionElement

这可能吗?如果是这样,语法是什么?

4 个答案:

答案 0 :(得分:5)

这在Swift中是不可能的。您可以在标准库中看到同样的事情:Array在使用Equatable元素声明时不会获得Equatable一致性。

答案 1 :(得分:1)

我建议使用包装器。例如

struct ArrayContainer<T: Decodable>: Container {
    let array: [T]
}

答案 2 :(得分:0)

Swift 4.2

在Swift 4.2中,我能够使用符合以下协议的元素来扩展数组:

public extension Array where Element: CustomStringConvertible{
    public var customDescription: String{
        var description = ""
        for element in self{
            description += element.description + "\n"
        }

        return description
    }
}

答案 3 :(得分:0)

我不知道这是最好的方法,还是苹果公司打算将其用于这种方式。我曾经使用过一次,对我来说效果很好:

假设您具有以下协议

protocol MyProtocol {
    var test: Bool { get }
}

您可以对数组执行此操作

extension Array: MyProtocol where Element: MyProtocol {
    var test: Bool {
        return self.allSatisfy({ $0.test })
    }
}

这对于字典

extension Dictionary: MyProtocol where Value: MyProtocol {
    var test: Bool {
        return self.values.allSatisfy({ $0.test })
    }
}