Codable 结构中的 Codable 变量导致错误 没有错误构建错误

问题描述

请看我的代码

没有错误

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
}

类型“人”不符合协议“可解码”

类型“人”不符合协议“可编码”

我不明白为什么会发生这种情况。它知道 selectedItem 符合 encodable & Decodable:

var selectedItem: Codable

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

谢谢!

解决方法

这里编译器的问题是,通常当一个类型定义为符合 Codable 时,编译器会为您合成代码,使 Person 在这种情况下符合协议。它通过为您创建 init(from decoder: Decoder) throws 的实现和 func 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()))