JSON解码时如何一次性设置Struct的pureWeight属性(无需手动全解码)
解决方案:保存JSON解析的原始weight值到pureWeight
嘿,我明白你的需求——想要让pureWeight固定保存JSON解析时weight的初始值,后续修改weight也不会影响它,还不想手动写一堆解码代码对吧?这里有两个实用的方案,看哪个更适合你:
方案1:自定义解码初始化器(简单直接)
如果你的结构体字段不多,直接自定义init(from:)是最直观的。我们先让默认的解码逻辑完成字段解析,然后立刻把刚解码出来的weight赋值给pureWeight:
struct CustomResponse: Decodable { var network: String var weight: Int = 0 let pureWeight: Int // 用let修饰,确保后续不能被意外修改 enum CodingKeys: String, CodingKey { case network, weight // 键名和属性名一致时可以简化写法 } init(from decoder: Decoder) throws { // 先解码出所有CodingKeys对应的属性 let container = try decoder.container(keyedBy: CodingKeys.self) network = try container.decode(String.self, forKey: .network) // 处理weight的可选情况(对应你原来的默认值0) weight = try container.decodeIfPresent(Int.self, forKey: .weight) ?? 0 // 把刚解码得到的原始weight值赋值给pureWeight pureWeight = weight } }
这样一来,pureWeight在解码完成后就固定下来了,后续修改weight完全不会影响它。
方案2:使用属性包装器(适合字段较多的场景)
如果你的结构体有很多字段,不想手动逐个解码,可以用@propertyWrapper来自动保存初始值,这样完全不用修改解码逻辑:
// 定义一个属性包装器,用来保存属性的初始值 @propertyWrapper struct InitialValue<T> { var wrappedValue: T let initialValue: T init(wrappedValue: T) { self.wrappedValue = wrappedValue self.initialValue = wrappedValue } } // 然后修改你的结构体 struct CustomResponse: Decodable { var network: String @InitialValue var weight: Int = 0 // pureWeight直接返回weight的初始值 var pureWeight: Int { _weight.initialValue } enum CodingKeys: String, CodingKey { case network, weight } }
这个方案里,当JSON解码weight时,属性包装器的init(wrappedValue:)会被自动调用,把解码得到的原始值存在initialValue里。后续不管你怎么修改weight,pureWeight都会返回一开始的初始值,而且完全不用手动写解码代码!
两种方案都能满足你的需求,选哪个看你的结构体复杂度就行~
内容的提问来源于stack exchange,提问作者Coldfish
相关产品推荐
相关产品推荐

