Swift枚举优化:能否移除所有调用中的.rawValue?
当然可以啦!只要做些小调整,就能彻底摆脱每次调用枚举都要写.rawValue的繁琐,下面分几种常见场景给你拆解:
1. 让枚举遵循
Codable协议(最推荐) 如果你的枚举是用来处理JSON编解码的,直接让它遵循Codable(配合String/Int这类RawRepresentable类型作为raw值),Swift会自动帮你生成编码/解码逻辑,全程都不用手动写解码器,更不用碰.rawValue。
举个例子:
// 枚举直接遵循String和Codable enum UserStatus: String, Codable { case active, inactive, pending } // 结构体也遵循Codable,直接用枚举类型作为属性 struct AppUser: Codable { let username: String let status: UserStatus } // 解码示例 let sampleJSON = """ {"username": "Luna", "status": "active"} """.data(using: .utf8)! let decodedUser = try JSONDecoder().decode(AppUser.self, from: sampleJSON) // 使用时直接调用枚举实例,完全不需要.rawValue if decodedUser.status == .active { print("用户处于活跃状态") }
这种方式最省心,Swift会自动把JSON里的字符串和枚举的rawValue做映射,外部调用时直接用枚举case就行。
2. 自定义解码器时内部处理rawValue转换
如果因为特殊业务逻辑(比如非标准的raw值映射)必须自己写解码器,那可以把rawValue的转换逻辑封装在解码器内部,这样外部调用时就不用再写.rawValue了。
示例代码:
enum OrderStatus: String { case confirmed, shipped, delivered } struct Order: Decodable { let orderID: String let status: OrderStatus enum CodingKeys: String, CodingKey { case orderID, status } init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) orderID = try container.decode(String.self, forKey: .orderID) // 在这里完成rawValue的转换,外部完全感知不到 let statusRaw = try container.decode(String.self, forKey: .status) guard let orderStatus = OrderStatus(rawValue: statusRaw) else { throw DecodingError.dataCorruptedError( forKey: .status, in: container, debugDescription: "无效的订单状态值" ) } self.status = orderStatus } } // 使用时直接用枚举实例 let order = try JSONDecoder().decode(Order.self, from: orderData) switch order.status { case .confirmed: print("订单已确认") case .shipped: print("订单已发货") case .delivered: print("订单已送达") }
这样外部使用Order的status属性时,拿到的直接是OrderStatus枚举实例,调用逻辑时完全不需要加.rawValue。
3. 给枚举添加便捷属性(兼容旧逻辑场景)
如果有些场景还是需要获取raw值,但又不想每次写.rawValue,可以给枚举加个简洁的计算属性来替代:
enum PaymentMethod: String { case creditCard, paypal, applePay // 用自定义属性替代rawValue var type: String { rawValue } } // 使用时直接调用.type,比.rawValue更直观 print(PaymentMethod.creditCard.type)
不过这种方式只是简化写法,不如前两种彻底,适合需要兼容旧代码的过渡场景。
总的来说,优先选择让枚举遵循Codable(如果是编解码场景),能最大程度减少冗余代码;如果必须自定义解码器,就把rawValue的转换逻辑藏在内部,让外部调用更简洁。
内容的提问来源于stack exchange,提问作者Riccardo Perego
相关产品推荐
相关产品推荐

