为什么我的特殊 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 明确声明 Array
是 Decodable
如果它们的元素是。你只需要做同样的事情:
extension Array : JsonDecodable where Element : JsonDecodable {
static func decode(data: Data?, decoder: JSONDecoder) -> Self? {
// Decode each element and return an array
}
}
这使用了一个名为 "Conditional Conformance" 的功能,如果容器持有的类型也符合该协议,则它通常允许容器符合协议。
使用 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 明确声明 Array
是 Decodable
如果它们的元素是。你只需要做同样的事情:
extension Array : JsonDecodable where Element : JsonDecodable {
static func decode(data: Data?, decoder: JSONDecoder) -> Self? {
// Decode each element and return an array
}
}
这使用了一个名为 "Conditional Conformance" 的功能,如果容器持有的类型也符合该协议,则它通常允许容器符合协议。