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

Swift中Codable如何处理包含多种数据模型的Any类型字段

优化方案

你当前实现存在两个核心问题:

  • Any类型不兼容Codable协议,后续如果需要将OverviewWorkout实例做序列化操作会直接报错
  • 后续使用data字段时需要手动做类型判断和强转,代码冗余且容易出现类型转换错误

推荐你用带关联值的枚举替代Any类型来包裹不同格式的data字段,完全适配你的业务场景,改造后的代码如下:

import Foundation

struct OverviewWorkout : Codable {
    
    enum WorkoutType: String, Codable {
        case workout
        case coach
        case bodyArea
        case challenge
        case title
        case group
        case trainer
    }

    // 用带关联值的枚举统一包裹所有可能的data类型
    enum WorkoutData: Codable {
        case singleWorkout(Workout)
        case coachInstruction(CoachInstruction)
        case workoutList([Workout])
        case title(Title)
        case trainerList([Trainer])
    }

    var type: WorkoutType
    var data : WorkoutData

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        type = try container.decode(WorkoutType.self, forKey: .type)
        switch type {
        case .workout, .challenge:
            data = .singleWorkout(try container.decode(Workout.self, forKey: .data))
        case .coach:
            data = .coachInstruction(try container.decode(CoachInstruction.self, forKey: .data))
        case .bodyArea, .group:
            data = .workoutList(try container.decode([Workout].self, forKey: .data))
        case .title:
            data = .title(try container.decode(Title.self, forKey: .data))
        case .trainer:
            data = .trainerList(try container.decode([Trainer].self, forKey: .data))
        }
    }

    private enum CodingKeys: String, CodingKey {
        case type,data
    }
}

extension OverviewWorkout {
    struct Title: Codable {
        let title: String
    }
}

改造后的代码优势:

  • 完全兼容Codable协议,解码、编码都能正常执行
  • 类型安全,后续使用data时不需要强制类型转换,直接匹配枚举的关联值即可拿到对应类型的模型:
    // 调用示例
    let overviewData: OverviewWorkout = ...
    switch overviewData.data {
    case .singleWorkout(let workout):
        // 直接使用Workout类型的workout实例
    case .coachInstruction(let coach):
        // 直接使用CoachInstruction类型的coach实例
    // 其他类型匹配逻辑
    }
    
  • 后续新增data类型只需要在WorkoutData枚举里新增对应case,可扩展性极强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:45:01