Codable 结构中的 Codable 变量导致错误

Codable variable inside Codable struct causes error

请看我的代码:

没有错误

struct Person: Codable {
    var name: String
    var age: Double
    var birthday: Date
    
    var selectedItem: Car
}

struct Car: Codable {
    var companyName: String
    var creationDate: Date
}

struct iPhone: Codable {
    var model: String
    var creationDate: Date
    var isScreenBroken: Bool = true
}

构建错误

struct Person: Codable { // "Type 'Person' does not conform to protocol 'Decodable'", "Type 'Person' does not conform to protocol 'Encodable'"
    var name: String
    var age: Double
    var birthday: Date
    
    var selectedItem: Codable // I've changed this line
}

struct Car: Codable {
    var companyName: String
    var creationDate: Date
}

struct iPhone: Codable {
    var model: String
    var creationDate: Date
    var isScreenBroken: Bool = true
}

Type 'Person' does not conform to protocol 'Decodable'

Type 'Person' does not conform to protocol 'Encodable'

我不明白为什么会这样。它知道 selectedItem 符合 Encodable & Decodable:

var selectedItem: Codable

我是 Swift 中协议的新手,所以请在回答时尝试解释这里发生的事情。

谢谢!

这里编译器的问题是,通常当一个类型被定义为符合 Codable 时,编译器会为您合成代码,使 Person 在这种情况下符合协议。它通过为您创建 init(from decoder: Decoder) throwsfunc encode(to encoder: Encoder) throws 之一的实现来做到这一点。

但是当您将 selectedItem 更改为 Codable 类型时,编译器将无法再合成这些方法,因为它需要确切地知道 selectedItem 的类型必须具有哪些属性正确生成代码。

这里需要做的就是使用generics

struct Person<T: Codable>: Codable {
    var name: String
    var age: Double
    var birthday: Date

    var selectedItem: T
}

struct Car: Codable {
    var companyName: String
    var creationDate: Date
}

struct iPhone: Codable {
    var model: String
    var creationDate: Date
    var isScreenBroken: Bool = true
}

然后编译器又高兴了,你可以像这样使用它

let person = Person(name: "Joe", age: 40, birthday: date, selectedItem: Car(companyName: "Ford", creationDate: Date()))