结构体Item不遵循Decodable/Codable协议问题求助
嘿,我来帮你捋清楚这个问题~ 当你把结构体里的weightOld改成weightNew后,Item突然不遵循Codable/Decodable协议,大概率是下面几个常见原因导致的,我们一步步来排查解决:
核心逻辑:自动合成Codable的前提
Swift的Codable协议支持自动实现编码解码,但有个硬性要求:结构体里所有存储属性都必须遵循Codable,同时解码时属性名要和JSON字段名匹配(或者通过自定义键映射)。一旦某个属性不满足,整个类型就无法自动合成协议实现。
常见问题与对应解决方法
问题1:Weight类型本身没遵循Codable
如果你的Weight结构体/类没有声明遵循Codable,那weightNew: [Weight]这个属性自然不符合Codable要求,直接导致Item无法通过自动合成满足协议。
解决方法:给Weight加上Codable协议声明:
struct Weight: Codable { // 这里放Weight的具体属性,比如: var value: Double var unit: String }
问题2:JSON字段名和属性名不匹配
如果原来的JSON数据里,对应的字段还是"weightOld",但你把属性改成了weightNew,自动合成的Decodable会尝试寻找键名为"weightNew"的字段,找不到就会抛出解码错误,进而提示类型不遵循协议。
解决方法:自定义CodingKeys来映射字段名和属性名:
struct Item: Codable { var weightNew: [Weight] // 其他属性... // 自定义编码解码键 enum CodingKeys: String, CodingKey { case weightNew = "weightOld" // 将JSON里的"weightOld"映射到weightNew属性 // 别忘了添加其他属性对应的键 // case name, price... } }
问题3:JSON中该字段可能缺失
如果JSON数据里有时候不存在这个重量字段,但你把weightNew声明为非可选的[Weight],自动解码时会因为找不到必填字段而失败,触发协议不遵循的报错。
解决方法:把属性改成可选类型:
var weightNew: [Weight]?
问题4:手动排查解码细节
如果以上方法都没用,你可以手动实现init(from:)方法,打印错误信息来定位具体问题:
struct Item: Decodable { var weightNew: [Weight] // 其他属性... init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 捕获解码weightNew的错误并打印 do { weightNew = try container.decode([Weight].self, forKey: .weightNew) } catch { print("解码weightNew时出错:\(error)") throw error } // 解码其他属性... } enum CodingKeys: String, CodingKey { case weightNew // 其他键... } }
总结
最常见的情况就是Weight没遵循Codable,或者属性名和JSON字段不匹配。按照上面的步骤逐一排查,应该就能解决问题啦~
内容的提问来源于stack exchange,提问作者arakweker

