如何在Swift的guard case语句else子句中仅获取.failure值?
解决方法:在Guard Else分支里直接处理Failure,避免嵌套和Switch穷举
Swift其实能推断出guard case .success的else分支里,result肯定是.failure状态,但因为MyError是枚举(哪怕只有一个case),Swift的switch语法必须穷举所有可能,所以才会报错。下面给你几个实用的办法,既能解决这个问题,还能保持成功逻辑不嵌套:
办法1:直接利用类型推断,跳过Switch
既然编译器已经确定else分支里只有.failure,而你的MyError只有一个case,直接执行错误逻辑就行:
func create() { let result = createResult(...) // -> Result<Data, MyError> guard case let .success(resultData) = result else { self.isError = true return } // 成功逻辑代码... }
要是以后MyError加了其他case,用if case替代switch就不用管穷举的问题了:
guard case let .success(resultData) = result else { if case .failure(.error) = result { self.isError = true } else if case .failure(.anotherError) = result { // 处理其他错误场景 } return }
办法2:在Guard里直接绑定Failure的值
你可以调整guard的写法,直接拿到failure的关联值,不用额外判断:
func create() { let result = createResult(...) // -> Result<Data, MyError> guard case .success(let resultData) = result else { // 这里强制解包绝对安全,编译器已经知道是failure了 let error = result.failure! if case .error = error { self.isError = true } return } // 成功逻辑代码... }
办法3:扩展Result类型(可选,更顺手)
如果经常要这么写,给Result加个扩展属性,用起来更方便:
extension Result { var failureValue: Failure? { guard case .failure(let error) = self else { return nil } return error } } // 使用示例: func create() { let result = createResult(...) // -> Result<Data, MyError> guard case let .success(resultData) = result else { if case .error = result.failureValue! { self.isError = true } return } // 成功逻辑代码... }
另外,你不想让成功代码嵌套的需求,用guard语法本来就已经满足了,上面这些办法都是优化else分支的错误处理,解决switch穷举的问题而已。
内容的提问来源于stack exchange,提问作者ansavchenco
相关产品推荐
相关产品推荐

