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

是否可在JsonDecoder中支持解析多种不同数据类型的结构体?

核心问题分析

原方案存在两处核心错误:

  • JSONDecoder.decode()要求传入的是遵循Decodable的具体类型,协议本身不遵循Decodable,因此直接传入CommonStruct.type不符合方法参数要求
  • 函数参数标注的data: CommonStruct类型错误,decode方法的from入参要求是Data类型,二者类型完全不匹配

可行方案:使用带关联值的枚举封装两种类型

这是Swift中处理「同一份数据可能匹配多种解析类型场景的标准实现方案,无需额外配置JSONDecoder,仅需自定义解析逻辑即可。

第一步:先让两个结构体遵循Decodable和公共协议

struct StructA: Decodable, CommonStruct {
   let someBool: Bool
}

struct StructB: Decodable, CommonStruct {
   let someString: String
}

protocol CommonStruct {}

第二步:定义多类型封装枚举,实现自定义解析逻辑

enum MultiStruct: Decodable {
    case a(StructA)
    case b(StructB)
    
    init(from decoder: Decoder) throws {
        // 优先尝试解析为StructA
        if let structA = try? StructA(from: decoder) {
            self = .a(structA)
            return
        }
        // StructA解析失败时尝试解析为StructB
        if let structB = try? StructB(from: decoder) {
            self = .b(structB)
            return
        }
        // 两种类型都匹配失败时抛出解析错误
        throw DecodingError.dataCorrupted(.init(
            codingPath: decoder.codingPath,
            debugDescription: "数据无法匹配StructA或StructB类型"
        ))
    }
    
    // 如果你需要统一返回公共协议类型可添加该计算属性
    var commonValue: CommonStruct {
        switch self {
        case .a(let a): return a
        case .b(let b): return b
        }
    }
}

第三步:修改业务函数实现

func needToGetShitDone(data: Data) throws {
    let result = try JSONDecoder().decode(MultiStruct.self, from: data)
    // 按解析结果分支处理
    switch result {
    case .a(let structA):
        // 处理StructA逻辑
        print(structA.someBool)
    case .b(let structB):
        // 处理StructB逻辑
        print(structB.someString)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:09:00