Почему мой специальный протокол Codable работает иначе, чем Swift Codable с Array? - PullRequest
0 голосов
/ 26 февраля 2019

С помощью 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 

2 строкивыше скомпилировать без проблем.

Теперь я хочу создать новый протокол, похожий на 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? {
        ....
    }
}

Когда я использую, попробуйте использовать JsonDecodable так же, как я делаю с Codable, я получаюследующая ошибка компилятора

Тип '[Person]' не имеет члена 'decode';

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

Как мне получить JsonDecodable для декодирования в массивмодели так же, как я могу при расширении Codable?

1 Ответ

0 голосов
/ 26 февраля 2019

Сообщение об ошибке могло бы быть более полезным, если бы оно использовало несимметричное имя типа:

Тип 'Array ' не имеет члена 'decode';

Person может соответствовать вашему протоколу, но Array - нет.Swift явно объявляет, что Array s Decodable, если их элементы.Вам просто нужно сделать то же самое:

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

При этом используется функция, называемая "Условное соответствие" , которая позволяет контейнерам в целом соответствовать протоколу, если тип, который они содержат, также делает.

...