如何 return 一个 Swift 枚举来处理错误条件

How to return a Swift enum for handling error conditions

我正在尝试在 Swift 中创建一个简单的错误处理结构。我想要做的是 return 一种包含 'Success' 代码或 'Error' 代码的类型。但为了让它有点棘手,在错误情况下,我还想获得一条消息和一个诊断字符串。

我想到了这个,它编译得很好并且在 returning success/error 方面工作得很好:

enum PasswordValidationResult {
    case Success
    case PasswordError(message: String, diagnostic: String)

    func isValid() -> Bool {
        switch self {
        case .Success:
            return true
        case .PasswordError:
            return false
        }
    }
}

我可以 return 所需的值:

return PasswordValidationResult.PasswordError(message: "You can't do that", diagnostic: "XYZ")

当我尝试引用 return 值时出现问题。

显然,我可以使用 isValid() 函数来测试成功条件,但我找不到任何引用消息和诊断字符串的语法。

例如,试试这个:

  myError = someFunction()

  if myError == PasswordValidationResult.Error {
    // None of this will compile, at all...
    println(myError.message)
  }

您可以使用 switch:

提取枚举的关联值
switch someFunction() {
case .Success:
    println("It worked!")
case .PasswordError(let message, let diag):
    println(message)
}

switch 做的其他好事之一是,如果您的情况用尽了所有可能性(如此处 - 枚举必须是两个值之一),则不需要默认值。如果您忘记或遗漏了一个,编译器会警告您。

注意,您还可以匹配特定值:

switch someFunction() {
case .Success:
    println("It worked!")
case .PasswordError("Password invalid", _):
    println("Please try again")
case let .PasswordError(message, diag):
    // more general error handling
}

访问这些值的另一种稍微更方便的方法是为每个关联值向 enum 添加计算属性:

enum PasswordValidationResult {
    // ...

    var errorMessage: String? {
        switch self {
        case let .PasswordError(message, _):
            return message
        default:
            return nil
        }
    }

    var errorDiagnostic: String? {
        switch self {
        case let .PasswordError(_, diagnostic):
            return diagnostic
        default:
            return nil
        }
    }
}

这些属性将 nil 表示成功,并让您在结果出错时轻松访问所需的值。

您可以使用 switch:

将关联值提取为具有元素名称的元组
let myError = someFunction()

switch myError {
case .Success:
    println("success")
case .PasswordError(let err):
    println("message: \(err.message)")
    println("diagnostic: \(err.diagnostic)")
}