You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:27:48