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
相关产品推荐
相关产品推荐

