【发布时间】:2025-12-28 01:50:11
【问题描述】:
当在 Swift 3 中调用 throws 的函数时,您必须详尽无遗地捕捉所有可能的错误,这通常意味着您在末尾有一个不必要的额外 catch {} 来处理不会发生的错误。
是否可以说throws MyErrorType,以便编译器知道您在处理该枚举中的所有情况时确实已经详尽无遗?
【问题讨论】:
当在 Swift 3 中调用 throws 的函数时,您必须详尽无遗地捕捉所有可能的错误,这通常意味着您在末尾有一个不必要的额外 catch {} 来处理不会发生的错误。
是否可以说throws MyErrorType,以便编译器知道您在处理该枚举中的所有情况时确实已经详尽无遗?
【问题讨论】:
我对这个问题的建议是在你的函数中返回 Result 类型而不是抛出错误。会是这样的。
enum MyCustomError: Error {
case genericError
}
func operationThatFails() -> Result<Response, MyCustomError> {
guard requiredConsition() else {
return .failure(.genericError)
}
return Response()
}
然后你可以像这样处理错误:
let result = operationThatFails()
switch result {
case .success(let value):
// handle success
case .failure(let error):
// handle error
}
这样你的错误总是类型安全的
【讨论】:
没有简单的方法可以保证抛出错误的类型安全。考虑到这一点,如果编译器允许您指定 throws MyErrorType,那么它还必须确保在该函数体内您不是 trying 一个可能在 do/catch 块之外抛出不同类型的函数. (好吧,但它会增加不必要的复杂性)。 Swift 编译器可能已经很慢并且在推断类型时会陷入循环,推断 Thrown 类型一直沿抛出函数链向上可能是一场噩梦。
目前的想法是,对于大多数错误,无论如何您都将以一小部分方式处理它们。
话虽如此,您无需添加额外的 catch let error as MyErrorType 子句,您可以像这样在 catch 块中简单地使用开关:
do {
try something()
} catch let e {
switch e {
case let m as MyErrorType: handleMyError(m)
case let o as OtherErrorType: handleOther(o)
case is ThirdErrorType: print("error \(e)")
default: handleElse(e)
}
}
【讨论】: