Swift移除CodingKeys的amount、currencyCode后Product不遵循Decodable问题
问题解析:显式定义CodingKeys后为何必须列出同名属性
核心逻辑:显式CodingKeys会覆盖自动合成规则
当你在Codable结构体中显式定义CodingKeys枚举时,Swift会放弃对所有属性的自动编码/解码逻辑合成,仅处理枚举中列出的成员。结构体的解码初始化逻辑完全依赖你指定的CodingKeys集合。
报错代码原因分析
public struct Product: Codable { let productID, productDescription: String let amount: Double let currencyCode, productItemID, state, lastUpdated: String let remaining: Int enum CodingKeys: String, CodingKey { case productID = "productid" case productDescription = "description" // 移除这两个成员后编译报错 // case amount, currencyCode case productItemID = "productItemid" case state, lastUpdated, remaining } }
这里的amount和currencyCode是无默认值的存储属性,但未被加入CodingKeys:
- 解码时,Swift自动生成的Decodable实现只会处理CodingKeys中列出的属性
- 由于
amount和currencyCode没有默认值,解码后无法生成完整的Product实例,因此编译器判定结构体不满足Decodable协议要求。
可编译代码原因分析
public struct Product: Codable { let productID = "" let productDescription = "" let amount = 0.00 let currencyCode = "" let productItemID = "" let state = "" let lastUpdated = "" enum CodingKeys: String, CodingKey { case productID = "productid" case productDescription = "description" case productItemID = "productItemid" } }
这个例子中所有属性都带有默认值:
- 即使CodingKeys未列出
amount、currencyCode等属性,解码时Swift会自动用属性的默认值填充这些未被解码的字段 - 结构体可以正常完成初始化,因此符合Codable协议的要求。
总结
显式定义CodingKeys后,若结构体存在无默认值的存储属性,必须将这些属性全部加入CodingKeys枚举(无论属性名与JSON键名是否一致),否则解码时无法生成完整实例;如果属性带有默认值,则无需在CodingKeys中列出,初始化时会自动使用默认值补全。
内容的提问来源于stack exchange,提问作者jacobcan118
相关产品推荐
相关产品推荐

