Swift含关联值的ErrorType枚举无法用==比较的问题及解决
问题原因
Swift 里,带关联值的枚举,编译器不会自动给它合成Equatable协议实现——毕竟关联值的相等逻辑得由开发者明确定义。而不带关联值的枚举,编译器会自动生成默认的Equatable实现,所以你删掉带关联值的errorC(String)后,==就能正常用了。
解决方法
结合你只需要判断特定错误、不想全量处理100+错误类型的需求,推荐这几个高效方案:
方案1:用模式匹配直接判断目标case
不用让整个枚举遵循Equatable,直接用if case做模式匹配,这是最轻量化的方式:
func showError(_ error: Error) { guard let customError = error as? ErrorType else { return } // 直接判断是否为.errorA,完全不用管其他case if case .errorA = customError { // 这里写errorA的处理逻辑 print("处理ErrorA") } }
方案2:让枚举遵循Equatable(按需实现)
如果之后还要用到更多==比较,可以让ErrorType遵循Equatable,手动实现相等逻辑——只处理你需要比较的case就行,其他case按默认逻辑返回false:
enum ErrorType: Error, Equatable { case errorA case errorB case errorC(String) static func == (lhs: ErrorType, rhs: ErrorType) -> Bool { switch (lhs, rhs) { case (.errorA, .errorA): return true case (.errorB, .errorB): return true case let (.errorC(leftStr), .errorC(rightStr)): return leftStr == rightStr // 要是需要比较errorC的关联值就写这个 default: return false } } }
之后就能直接用==比较:
func showError(_ error: Error) { guard let customError = error as? ErrorType else { return } if customError == .errorA { // 处理逻辑 } }
方案3:给枚举加判断特定错误的便捷方法
如果要多次判断某个特定错误,给枚举加个便捷方法,可读性更好:
enum ErrorType: Error { case errorA case errorB case errorC(String) func isErrorA() -> Bool { if case .errorA = self { return true } return false } }
使用时直接调用方法:
func showError(_ error: Error) { guard let customError = error as? ErrorType else { return } if customError.isErrorA() { // 处理逻辑 } }
内容的提问来源于stack exchange,提问作者tech_human
相关产品推荐
相关产品推荐

