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

