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

Swift中如何运行时解码类型动态变化的结构体属性

实现方案

完全可以在运行时兼容两种返回格式的正常解码,不需要提前根据请求参数判断返回类型,也不用改接口请求逻辑,只要给League自定义Codable解码逻辑,对standings字段做两种类型的适配即可。

代码实现

你现有的结构体定义不需要大改,只要手动实现init(from:)解码方法,单独处理standings字段的类型兼容即可,其余字段解码逻辑和原来保持一致:

struct League: Codable {
    let standings: [Standing]?
    // 保留原有其余属性定义,不需要修改

    enum CodingKeys: String, CodingKey {
        case standings
        // 补全其余所有属性对应的CodingKey,和原有字段映射一致
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 先尝试按一维数组格式解码
        if let singleStandings = try? container.decode([Standing].self, forKey: .standings) {
            self.standings = singleStandings
        }
        // 一维格式解码失败,尝试按二维数组格式解码
        else if let groupedStandings = try? container.decode([[Standing]].self, forKey: .standings) {
            // 按你当前的[Standing]类型定义,直接把二维数组拍平成一维即可
            // 如果业务需要保留分组结构,可参考后面的扩展方案调整属性类型
            self.standings = groupedStandings.flatMap { $0 }
        }
        // 两种格式都不匹配时赋值nil,和原有可选类型逻辑对齐
        else {
            self.standings = nil
        }

        // 其余属性按原有逻辑正常解码即可,例:
        // self.id = try container.decode(Int.self, forKey: .id)
        // self.leagueName = try container.decode(String.self, forKey: .leagueName)
    }
}

扩展:需要区分两种格式的场景

如果你的业务需要识别返回的是单组排名还是多分组排名(比如多分组要展示分组标题、切换列表样式),可以不用拍平二维数组,定义枚举封装两种类型即可:

enum StandingsResult {
    case singleGroup([Standing])
    case multiGroup([[Standing]])
}

把League中的standings类型替换为StandingsResult?,在解码的两个分支分别给枚举赋值对应关联值即可,后续使用时通过switch判断枚举值就能拿到对应格式的数据。

这套逻辑是运行时自动匹配类型,和你传入的请求参数、列表点击回调逻辑完全解耦,同个endpoint不管返回哪种格式的standings都能正常解析,不会影响其他字段的解码正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:18:15