1

我四处搜索了一下,找不到任何东西——甚至在这个网站上都没有问题——所以现在我想知道 Swift 2 是否像 Java 那样支持多捕获块。

Java-示例:

try {
    someMethod(); // throws ExceptionOne, ExceptionTwo
} catch(ExceptionOne | ExceptionTwo e) {
    handleMyException();
} catch(Exception e2) {
    handleOtherExceptions();
}

在 Swift 中,我无法实现类似的解决方案。这个问题解释了一种处理一个ErrorType枚举的不同错误的好方法,但我的要求似乎不同,因为我的错误是用来自 HTTP 响应的消息初始化的。这是我的枚举:

enum HTTPError: ErrorType {
    case BAD_REQUEST(message: String)
    case UNAUTHORIZED(message: String)
    case NOT_FOUND
    case INTERNAL_SERVER_ERROR(message: String)
    case NOT_IMPLEMENTED(message: String)

    static func getErrorForStatusCode(statusCode: Int, message: String? = nil) -> HTTPError {
        switch statusCode {
        case 400:
            return HTTPError.BAD_REQUEST(message: message!)
        case 401:
            return HTTPError.UNAUTHORIZED(message: message!)
        case 404:
            return HTTPError.NOT_FOUND
        case 500:
            return HTTPError.INTERNAL_SERVER_ERROR(message: message!)
        case 501:
            return HTTPError.NOT_IMPLEMENTED(message: message!)
        default:
            return HTTPError.INTERNAL_SERVER_ERROR(message: message!)
        }
    }
}

当我想抛出该枚举的错误时,我使用这样的代码:

func someMethod() throws {
    ...
    HTTPError.getErrorForStatusCode(400, message: "Field X missing") // Actual values coming from HTTP-response
    ...
}

现在,在调用方法中,我必须分别捕获枚举的每个错误,尽管我希望它们都做同样的事情(除了NOT_FOUND,但这并不重要):

try {
    someMethod() // throws
} catch HTTPError.BAD_REQUEST(let message) {
    // display 'message' to user
} catch HTTPError.UNAUTHORIZED(let message) {
    // display 'message' to user
} catch HTTPError.INTERNAL_SERVER_ERROR(let message) {
    // display 'message' to user
}
...

Swift 2 真的不包含 multi-catch 吗?还是有其他解决方案可以帮助我解决我的问题?

编辑:似乎我想要的行为不是很清楚:我想以同样的方式处理 HTTPError 类型的错误(HTTPError.NOT_FOUND 除外),这就是我要求多捕获的原因。

我仍然会实现一个通用的 catch-block 来覆盖所有我不知道的错误(例如超时、nil-access,...),但是那些带有后端消息的错误应该被特殊处理。

谢谢,胖乎乎的

4

3 回答 3

1

Swift 2 确实支持 multi-catch

从文档

您在 catch 之后编写一个模式来指示该子句可以处理哪些错误。如果 catch 子句没有模式,则该子句匹配任何错误并将错误绑定到名为 的局部常量error

所以得到那个error常量并使用一个switch语句。

do {
  try someMethod() // throws
} catch let error as HTTPError {
  switch error  {
  case .NOT_FOUND:
    print("not found")
  case let message: // handle all errors with a message
    print(message)
  }
}

或带catch图案

do {
  try someMethod() // throws
} catch HTTPError.NOT_FOUND {
    print("not found")
} catch let message {
    print(message)
}

这也是详尽无遗的,因为所有其他案例都有信息。

除此之外,您(开发人员)应该确切地知道枚举中的案例数量,以便您可以可靠地处理它们。

编辑:

另一种解决方案是associatedValueenum

  var associatedValue : String {
    switch self {
    case BAD_REQUEST(let value) : return value
    case UNAUTHORIZED(let value) : return value
    case INTERNAL_SERVER_ERROR(let value) : return value
    case NOT_IMPLEMENTED(let value) : return value
    default: return ""
    }
  }

并使用此 switch 语句

do {
  try someMethod() // throws
} catch HTTPError.NOT_FOUND {
  print("not found")
} catch let error as HTTPError {
  print(error.associatedValue)
}
于 2016-02-14T21:14:11.073 回答
0
enum Error: ErrorType {
    case E1
    case E2
    case E3
}

func foo(e: Error) throws {
    throw e
}

do {
    try foo(Error.E2)
} catch Error.E1 {
    print(Error.E1) // only Error.E1
} catch {
    print("error: ", error) // all other errors
}
/*
error:  E2
*/
于 2016-02-14T21:13:13.053 回答
0

Swift 5.3 现在支持多模式捕获检查提案详细信息: https ://github.com/apple/swift-evolution/blob/master/proposals/0276-multi-pattern-catch-clauses.md

于 2020-08-28T14:38:58.500 回答