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

Swift自定义Decoder如何处理嵌套Container不存在时的nil值问题

解决方法

你当前代码崩溃的核心原因是nestedContainer(keyedBy:forKey:)方法在对应key不存在时会直接抛出解码错误,只需将这一步改为可选判断逻辑即可兼容name字段完全缺失的场景,修改后的完整代码如下:

struct UserModel: Decodable {
    var gender: String
    var title: String?
    var first: String?
    var last: String?
    
    // 顶层编码键
    enum CodingKeys: String, CodingKey {
        case name, gender
    }
    
    enum NameKeys: CodingKey {
        case title, first, last
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        gender = try container.decode(String.self, forKey: .gender)
        // 新增判断:只有name字段存在时才解析内部字段
        if container.contains(.name) {
            let name = try container.nestedContainer(keyedBy: NameKeys.self, forKey: .name)
            title = try name.decodeIfPresent(String.self, forKey: .title)
            first = try name.decodeIfPresent(String.self, forKey: .first)
            last = try name.decodeIfPresent(String.self, forKey: .last)
        }
        // 如果name字段不存在,三个可选属性默认保持nil即可
    }
}

可选替代写法

如果你不想用contains判断,也可以用try?捕获获取嵌套容器的错误,效果完全一致:

init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    gender = try container.decode(String.self, forKey: .gender)
    // 获取嵌套容器失败时直接跳过解析
    if let name = try? container.nestedContainer(keyedBy: NameKeys.self, forKey: .name) {
        title = try name.decodeIfPresent(String.self, forKey: .title)
        first = try name.decodeIfPresent(String.self, forKey: .first)
        last = try name.decodeIfPresent(String.self, forKey: .last)
    }
}

两种写法都可以实现:就算顶层name字段完全缺失,解码也能正常完成,title、first、last三个属性会自动为nil,不会抛出崩溃错误。

内容的提问来源于stack exchange,提问作者Simon McNeil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:24:04