Swift中如何用Switch处理值相同但场景不同的枚举
问题:Swift枚举相同原始值导致分支无法触发的解决办法
问题核心
你定义的ApiType枚举遵循String协议时,.usemeInLogin和.usemeInLogout使用了相同的原始值"authenticationAccessIdApi",但Swift会将拥有相同原始值的枚举case视为同一个实例:当通过原始值初始化或传递枚举值时,系统只会匹配第一个定义的case(即.usemeInLogin),后续的.usemeInLogout永远不会被选中,这就是分支无法触发的原因。
解决方案
方案1:用关联值区分业务场景(推荐)
将两个相同原始值的case合并,通过关联值标记业务场景,同时保留原始值的兼容性:
enum ApiType: String, CaseIterable { case dashboard = "dashboardRootIdApi" case profile = "profileRootIdApi" case authentication(scene: String) // 重写rawValue,保证认证场景返回统一字符串 override var rawValue: String { switch self { case .dashboard: return "dashboardRootIdApi" case .profile: return "profileRootIdApi" case .authentication: return "authenticationAccessIdApi" } } // 自定义初始化(若需从原始值转换,需额外上下文,否则返回nil) init?(rawValue: String) { switch rawValue { case "dashboardRootIdApi": self = .dashboard case "profileRootIdApi": self = .profile case "authenticationAccessIdApi": // 仅通过rawValue无法区分场景,建议直接用case创建实例 return nil default: return nil } } } // 业务处理函数修改 func authenticationDtoScreen(for type: ApiType) -> UIControllerSharedScreen { switch type { case .authentication(scene: "login"): return UIControllerScreenConfiguration(for: type, title: "Login") case .authentication(scene: "logout"): return UIControllerScreenConfiguration(for: type, title: "Logout") default: fatalError("Unsupported API type") } }
方案2:嵌套枚举拆分场景
把认证相关逻辑拆成子枚举,既保留统一原始值,又能明确区分场景:
enum ApiType: String, CaseIterable { case dashboard = "dashboardRootIdApi" case profile = "profileRootIdApi" case authentication(AuthenticationScene) enum AuthenticationScene: String { case login = "authenticationAccessIdApi" case logout = "authenticationAccessIdApi" } override var rawValue: String { switch self { case .dashboard: return "dashboardRootIdApi" case .profile: return "profileRootIdApi" case .authentication(let scene): return scene.rawValue } } } // 业务处理 func authenticationDtoScreen(for type: ApiType) -> UIControllerSharedScreen { switch type { case .authentication(.login): return UIControllerScreenConfiguration(for: type, title: "Login") case .authentication(.logout): return UIControllerScreenConfiguration(for: type, title: "Logout") default: fatalError("Unsupported API type") } }
方案3:修改原始值(若业务允许)
如果服务器端可以配合调整,直接给登录、登出设置不同的原始值,这是最直接的解决方式:
enum ApiType: String, CaseIterable { case dashboard = "dashboardRootIdApi" case profile = "profileRootIdApi" case usemeInLogin = "authenticationLoginApi" case usemeInLogout = "authenticationLogoutApi" }
此时你的原有switch分支可以正常触发。
方案4:添加枚举属性区分(局限性大)
若无法修改枚举结构,可给每个case添加场景属性,但仅适用于直接通过case创建枚举值的场景(从rawValue初始化仍会优先匹配第一个case):
enum ApiType: String, CaseIterable { case dashboard = "dashboardRootIdApi" case profile = "profileRootIdApi" case usemeInLogin = "authenticationAccessIdApi" case usemeInLogout = "authenticationAccessIdApi" var businessScene: String { switch self { case .usemeInLogin: return "login" case .usemeInLogout: return "logout" default: return self.rawValue } } }
内容的提问来源于stack exchange,提问作者User Unknown
相关产品推荐
相关产品推荐

