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

Swift 4 Decodable:如何将多个JSON值映射到单个枚举值?

刚好我之前处理过类似的枚举映射需求,给你提供一个简洁可靠的实现方案:

自定义Decodable初始化方法实现映射

因为默认的Decodable枚举解码只会严格匹配rawValue,所以我们需要手动实现init(from decoder:)方法来处理多值到单一枚举case的映射。以下是完整的代码:

enum ClothingType: String, Decodable {
    case SHIRT
    case PANTS
    case SHOES
    case HAT
    
    // 自定义解码逻辑,覆盖默认实现
    init(from decoder: Decoder) throws {
        // 获取JSON中的原始字符串值
        let container = try decoder.singleValueContainer()
        let rawString = try container.decode(String.self)
        
        // 按需求映射不同的原始值到对应的枚举case
        switch rawString {
        case "T_SHIRT", "LONG_SLEEVE_SHIRT":
            self = .SHIRT
        case "JEANS", "SHORTS":
            self = .PANTS
        case "SNEAKERS", "SANDALS":
            self = .SHOES
        case "BASEBALL_CAP", "WINTER_HAT":
            self = .HAT
        default:
            // 遇到未定义的字段时抛出明确的错误,方便调试
            throw DecodingError.dataCorruptedError(
                in: container,
                debugDescription: "无法识别的服装类型: \(rawString)"
            )
        }
    }
}

代码解释

  • 我们通过实现Decodable协议的init(from:)方法,完全掌控了解码逻辑,替代了系统自动生成的匹配rawValue的逻辑。
  • 使用singleValueContainer()获取JSON中的单个字符串值(因为你的枚举是基于String类型的)。
  • 通过switch语句把所有需要映射的JSON字段值,对应到对应的枚举case。
  • 最后添加default分支抛出错误,避免遇到未知值时出现静默失败,让调试更高效。

使用示例

你可以用一个测试结构体来验证这个实现:

struct ClothingItem: Decodable {
    let type: ClothingType
    let price: Double
}

// 测试用的JSON数据
let testJson = """
{
    "type": "JEANS",
    "price": 49.99
}
"""

do {
    let decoder = JSONDecoder()
    let item = try decoder.decode(ClothingItem.self, from: testJson.data(using: .utf8)!)
    print(item.type) // 输出: PANTS
} catch {
    print("解码失败: \(error.localizedDescription)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:03:02