如何构建可返回请求Payload的枚举并实现简洁调用
问题
我需要为不同的请求端点匹配对应的Payload,示例如下:
- getUser:payload:
{} - updateUser:payload:
{"age": 10, "gender": "M"} - createMaleUser:payload:
{"age": 2, "gender": "M"}
我考虑了两种实现方案:
- 为每个请求编写独立函数并硬编码Payload
- 编写一个接收枚举参数的函数,根据参数获取Payload并发起请求,但不知道如何正确初始化枚举的关联值
当前我编写了如下代码:
extension ABC { public struct UserPayload { var age: Int var gender: String } } enum RequestType { case getUser case updateUser case createMaleUser case createFemaleUser var payload: UserPayload? { switch self { case .getUser: return nil case .updateUser: return UserPayload(age: 1000, gender: "M") case .createMaleUser: return UserPayload(age: 2, gender: "M") case .createFemaleUser: return UserPayload(age: 200, gender: "F") } } } request(.getUser.payload) /// 我希望能像request(.getUser)这样调用 func request(_ payload: RequestType) { ... }
但我希望能直接通过request(.getUser)这样的方式调用,尝试了如下写法但无法实现:
enum RequestType { case getUser = nil case updateUser = UserPayload(age: 1000, gender: "M") case createMaleUser = UserPayload(age: 2, gender: "M") case createFemaleUser = UserPayload(age: 200, gender: "F") }
请问该如何实现这一需求?
解决方案
方法1:直接修改request函数逻辑
不需要改动现有枚举的定义,只需要调整request函数的参数类型,并在函数内部通过枚举的payload属性获取对应值即可:
// 保留原有的枚举和Payload定义 extension ABC { public struct UserPayload { var age: Int var gender: String } } enum RequestType { case getUser case updateUser case createMaleUser case createFemaleUser var payload: UserPayload? { switch self { case .getUser: return nil case .updateUser: return UserPayload(age: 1000, gender: "M") case .createMaleUser: return UserPayload(age: 2, gender: "M") case .createFemaleUser: return UserPayload(age: 200, gender: "F") } } } // 修改request函数,接收RequestType类型参数 func request(_ type: RequestType) { let targetPayload = type.payload // 这里使用targetPayload执行请求逻辑 print("发起请求:\(type),Payload:\(String(describing: targetPayload))") } // 现在可以直接按预期调用 request(.getUser) request(.updateUser)
方法2:给枚举添加关联值(适配动态场景)
如果后续需要支持动态传入自定义Payload(比如更新用户时动态指定年龄),可以给枚举添加关联值,同时保留默认Payload的快捷调用方式:
extension ABC { public struct UserPayload { var age: Int var gender: String } } enum RequestType { case getUser case updateUser(UserPayload?) case createMaleUser(UserPayload?) case createFemaleUser(UserPayload?) // 提供默认Payload的静态实例,方便快捷调用 static let updateUser = RequestType.updateUser(UserPayload(age: 1000, gender: "M")) static let createMaleUser = RequestType.createMaleUser(UserPayload(age: 2, gender: "M")) static let createFemaleUser = RequestType.createFemaleUser(UserPayload(age: 200, gender: "F")) // 统一获取实际Payload的计算属性 var actualPayload: UserPayload? { switch self { case .getUser: return nil case .updateUser(let payload), .createMaleUser(let payload), .createFemaleUser(let payload): return payload } } } func request(_ type: RequestType) { let targetPayload = type.actualPayload // 处理请求逻辑 } // 使用默认Payload调用 request(.updateUser) // 传入自定义Payload调用 request(.updateUser(UserPayload(age: 30, gender: "F"))) request(.getUser)
关于你之前写法失败的原因
Swift枚举的原始值(case xxx = 原始值)仅支持字符串、数字、布尔值这类字面量类型,无法直接赋值自定义结构体实例。而通过枚举的计算属性或关联值的方式,就能完美绕开这个限制,实现需求。
内容的提问来源于stack exchange,提问作者jacobcan118
相关产品推荐
相关产品推荐

