如何为Swift结构体添加布尔变量并解决JSON解码报错问题?
解决JSON解码时处理结构体中不存在的字段问题
当你给ProductData添加isFavourite后出现解码错误,本质是JSON里没有这个字段,但默认的Decodable实现会尝试解码所有结构体属性,找不到对应字段就会抛出错误。下面是几种可行的解决方式:
方法1:给isFavourite设置默认值
直接给变量添加默认值,Swift的自动合成Decodable实现会在JSON无对应字段时自动使用这个默认值,无需额外修改解码逻辑:
struct ProductData : Identifiable,Decodable,Hashable { var id : Int var title :String var type : String var description : String var filename : String var price : Float var rating : Int // 添加默认值,JSON无此字段时自动用false var isFavourite = false init() { self.id = 0 self.title = "" self.type = "" self.description = "" self.filename = "" self.price = 0.0 self.rating = 0 self.isFavourite = false } }
方法2:通过CodingKeys排除不需要解码的字段
显式定义CodingKeys枚举,只包含JSON中存在的字段,这样Decodable会忽略不在枚举里的属性,你可以自由给isFavourite设置初始值:
struct ProductData : Identifiable,Decodable,Hashable { var id : Int var title :String var type : String var description : String var filename : String var price : Float var rating : Int var isFavourite = false // 只列出JSON里有的字段,isFavourite不在其中,解码时会被忽略 private enum CodingKeys: String, CodingKey { case id, title, type, description, filename, price, rating } init() { self.id = 0 self.title = "" self.type = "" self.description = "" self.filename = "" self.price = 0.0 self.rating = 0 self.isFavourite = false } }
方法3:自定义init(from:)解码方法
如果需要更灵活的控制,可以手动实现解码初始化方法,自己处理每个字段的解码,同时给isFavourite赋值:
struct ProductData : Identifiable,Decodable,Hashable { var id : Int var title :String var type : String var description : String var filename : String var price : Float var rating : Int var isFavourite : Bool init() { self.id = 0 self.title = "" self.type = "" self.description = "" self.filename = "" self.price = 0.0 self.rating = 0 self.isFavourite = false } // 自定义解码初始化 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decode(Int.self, forKey: .id) title = try container.decode(String.self, forKey: .title) type = try container.decode(String.self, forKey: .type) description = try container.decode(String.self, forKey: .description) filename = try container.decode(String.self, forKey: .filename) price = try container.decode(Float.self, forKey: .price) rating = try container.decode(Int.self, forKey: .rating) // 直接给isFavourite赋值默认值,不需要从JSON解码 isFavourite = false } private enum CodingKeys: String, CodingKey { case id, title, type, description, filename, price, rating } }
这三种方法里,方法1最简单,适合只需要默认值的场景;方法2适合明确区分哪些字段需要从JSON解码;方法3则适合需要额外解码逻辑的复杂场景。
内容的提问来源于stack exchange,提问作者Vinduja Narayanan K
相关产品推荐
相关产品推荐

