为什么我的特殊 Codable 协议与 Swift 的 Codable with Array 的工作方式不同?

Why does my special Codable protocol work differently than Swift's Codable with Array?

使用 Codable,我可以创建以下扩展程序

extension Decodable {
    public static func decode(data: Data, decoder: JSONDecoder = .default) -> Self? {
        do {
            return try decoder.decode(self, from: data)
        } catch let error as NSError {
            CodableKit.log(message: "\(error.userInfo)")
            return nil
        }
    }
}

并将其用于单个对象和数组类型,例如

let person = Person.decode(data: personData)   // single
let people = [Person].decode(data: peopleData) // array 

以上两行编译没有问题。

现在,我想创建一个类似于 Codable

的新协议
public typealias JsonCodable = JsonDecodable & JsonEncodable

public protocol JsonDecodable: Decodable {
    static func decode(data: Data?, decoder: JSONDecoder) -> Self?
}

extension JsonDecodable {
    static func decode(data: Data?, decoder: JSONDecoder) -> Self? {
        ....
    }
}

当我像使用 Codable 一样尝试使用 JsonDecodable 时,出现以下编译器错误

Type '[Person]' has no member 'decode';

let person = Person.decode(data: personData)   // this works
let people = [Person].decode(data: peopleData) // this does not

如何让 JsonDecodable 以与扩展 Codable 时相同的方式解码为模型数组?

如果使用未加糖的类型名称,错误消息可能更有用:

Type 'Array<Person>' has no member 'decode';

Person 可能符合您的协议,但 Array 不符合。 Swift 明确声明 ArrayDecodable 如果它们的元素是。你只需要做同样的事情:

extension Array : JsonDecodable where Element : JsonDecodable {
    static func decode(data: Data?, decoder: JSONDecoder) -> Self? {
        // Decode each element and return an array
    }
}

这使用了一个名为 "Conditional Conformance" 的功能,如果容器持有的类型也符合该协议,则它通常允许容器符合协议。