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

Swift能否将接收不同枚举参数的两个同类函数合并为单个泛型函数?

两个函数可以合并为通用泛型函数

两个函数的逻辑完全一致,唯一差异仅为入参的枚举类型,且两个枚举都具备String类型的rawValue属性,完全可以通过泛型约束实现合并。

合并后的基础实现

func setupListener<T: RawRepresentable>(event: T, handler: @escaping ([Any], SocketAckEmitter) -> Void) -> UUID? where T.RawValue == String {
    guard let client = self.client else {
        return nil
    }
    let listenerId = client.on(event.rawValue, callback: handler)
    return listenerId
}

泛型T的约束要求刚好匹配两个枚举的特性:遵循RawRepresentable协议可访问rawValue,且rawValue为String类型匹配Socket客户端on方法的事件名入参要求,逻辑和原两个函数完全一致。

调用方式

和原有两个函数的调用逻辑完全兼容,不需要修改现有调用侧代码:

// 原RushdownListenEvent场景调用
let rushdownListenerId = setupListener(event: 你的Rushdown枚举值, handler: { /* 原有回调逻辑 */ })
// 原HystoriaListenEvent场景调用
let hystoriaListenerId = setupListener(event: 你的Hystoria枚举值, handler: { /* 原有回调逻辑 */ })

可选优化:增加类型限制

如果需要避免其他无关的RawRepresentable类型被误传入函数,可以新增一个空协议让两个目标枚举遵循,再给泛型增加对应协议约束:

// 定义空的Socket监听事件标记协议
protocol SocketListenEvent {}
// 给两个目标枚举添加协议遵循
extension RushdownListenEvent: SocketListenEvent {}
extension HystoriaListenEvent: SocketListenEvent {}

// 优化后的泛型函数
func setupListener<T: RawRepresentable & SocketListenEvent>(event: T, handler: @escaping ([Any], SocketAckEmitter) -> Void) -> UUID? where T.RawValue == String {
    guard let client = self.client else {
        return nil
    }
    let listenerId = client.on(event.rawValue, callback: handler)
    return listenerId
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:09:00