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

如何构建可返回请求Payload的枚举并实现简洁调用

问题

我需要为不同的请求端点匹配对应的Payload,示例如下:

  • getUser:payload: {}
  • updateUser:payload: {"age": 10, "gender": "M"}
  • createMaleUser:payload: {"age": 2, "gender": "M"}

我考虑了两种实现方案:

  1. 为每个请求编写独立函数并硬编码Payload
  2. 编写一个接收枚举参数的函数,根据参数获取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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:27:42