【问题标题】:Can I restrict the type that a function throws in Swift?我可以限制函数在 Swift 中抛出的类型吗?
【发布时间】:2025-12-28 01:50:11
【问题描述】:

当在 Swift 3 中调用 throws 的函数时,您必须详尽无遗地捕捉所有可能的错误,这通常意味着您在末尾有一个不必要的额外 catch {} 来处理不会发生的错误。

是否可以说throws MyErrorType,以便编译器知道您在处理该枚举中的所有情况时确实已经详尽无遗?

【问题讨论】:

标签: swift swift3


【解决方案1】:

我对这个问题的建议是在你的函数中返回 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
}

这样你的错误总是类型安全的

【讨论】:

    【解决方案2】:

    没有简单的方法可以保证抛出错误的类型安全。考虑到这一点,如果编译器允许您指定 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)
      }
    }
    

    【讨论】:

    • Java 是如何解决这个问题的,而不会遇到您提到的 Swift 编译器会遇到的问题?我从来没有听说过在 Java 中实现检查的异常是缓慢或复杂的。