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

如何手动解码一组遵循自定义LogicBlock协议的Codable元素数组

核心解决思路

你只需要先解码出每个LogicBlock对象的typeID字段,匹配到对应的枚举值后,再用对应的具体结构体类型解码整个对象即可,完整实现如下:

1. 先定义通用CodingKey读取typeID

private enum CommonLogicBlockCodingKeys: String, CodingKey {
    case typeID
}

2. 实现类型判断与解码逻辑

修正你的decodeLogicBlock方法:

private static func decodeLogicBlock(from decoder: Decoder) throws -> LogicBlock {
    // 先读取typeID判断具体类型
    let container = try decoder.container(keyedBy: CommonLogicBlockCodingKeys.self)
    let typeID = try container.decode(LogicBlockTypeID.self, forKey: .typeID)
    
    switch typeID {
    case .a:
        return try Struct1(from: decoder)
    case .b:
        return try Struct2(from: decoder)
    case .c:
        // 注意你原代码中第三个结构体和Struct2重名,需修改为Struct3
        return try Struct3(from: decoder)
    }
}

3. 修正MyModel的解码实现

struct MyModel: Codable {
    var var1: String
    var var2: Int
    var logicBlocks: [LogicBlock]
    
    enum CodingKeys: String, CodingKey {
        case var1, var2, logicBlocks
    }
    
    init(from decoder: Decoder) throws {
        let rootContainer = try decoder.container(keyedBy: CodingKeys.self)
        // 解码普通属性
        var1 = try rootContainer.decode(String.self, forKey: .var1)
        var2 = try rootContainer.decode(Int.self, forKey: .var2)
        
        // 解码logicBlocks数组
        var blocksContainer = try rootContainer.nestedUnkeyedContainer(forKey: .logicBlocks)
        var parsedBlocks = [LogicBlock]()
        while !blocksContainer.isAtEnd {
            let blockDecoder = try blocksContainer.superDecoder()
            parsedBlocks.append(try Self.decodeLogicBlock(from: blockDecoder))
        }
        logicBlocks = parsedBlocks
    }
    
    // 若需要支持编码功能,需补充实现encode方法
    func encode(to encoder: Encoder) throws {
        var rootContainer = encoder.container(keyedBy: CodingKeys.self)
        try rootContainer.encode(var1, forKey: .var1)
        try rootContainer.encode(var2, forKey: .var2)
        
        var blocksContainer = rootContainer.nestedUnkeyedContainer(forKey: .logicBlocks)
        try logicBlocks.forEach { block in
            try block.encode(to: blocksContainer.superEncoder())
        }
    }
}

注意事项

  • 你原代码中第三个遵循LogicBlock协议的结构体和Struct2重名,需要修改为独立命名比如Struct3,否则会触发编译错误
  • 如果后续新增LogicBlock的实现类型,只需要在decodeLogicBlock的switch分支中新增对应typeID的处理逻辑即可
  • 该方案要求服务端返回的每个LogicBlock对象中必须携带正确的typeID字段,值与你定义的LogicBlockTypeID枚举的rawValue对应即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:57:03