可以返回或错误的Swift方法的最佳实践

Mar*_*ean 6 swift

我正在练习Swift并且有一个场景(和方法),其结果可能是成功的,也可能是失败的.

这是一个安全服务类.我有一个方法,我可以使用电子邮件地址和密码进行身份验证,并希望User在凭据正确时返回实例,或者抛出某种形式的false值.

我有点困惑,因为我对Swift方法的理解是你需要指定一个返回类型,所以我有:

class SecurityService {
    static func loginWith(email: String, password: String) -> User {
        // Body
    }
}
Run Code Online (Sandbox Code Playgroud)

我在Go和Node.js方法中看到了返回"double"值的方法,其中第一个表示任何错误,第二个是"成功"响应.我也知道Swift没有错误或异常之类的东西(但是因为我正在学习Swift的早期版本,所以可能已经改变了).

在这种情况下,适当的做法是什么?

mix*_*xel 10

如果您想处理在登录过程中可能发生的错误,而不是使用Swift错误处理的强大功能:

struct User {
}

enum SecurityError: Error {
    case emptyEmail
    case emptyPassword
}

class SecurityService {
    static func loginWith(email: String, password: String) throws -> User {
        if email.isEmpty {
            throw SecurityError.emptyEmail
        }
        if password.isEmpty {
            throw SecurityError.emptyPassword
        }
        return User()
    }    
}

do {
    let user = try SecurityService.loginWith1(email: "", password: "")
} catch SecurityError.emptyEmail {
    // email is empty
} catch SecurityError.emptyPassword {
    // password is empty
} catch {
    print("\(error)")
}
Run Code Online (Sandbox Code Playgroud)

或转换为可选:

guard let user = try? SecurityService.loginWith(email: "", password: "") else {
    // error during login, handle and return
    return
}

// successful login, do something with `user`
Run Code Online (Sandbox Code Playgroud)

如果你只想得到Usernil:

class SecurityService {    
    static func loginWith(email: String, password: String) -> User? {
        if !email.isEmpty && !password.isEmpty {
            return User()
        } else {
            return nil
        }
    }
}

if let user = SecurityService.loginWith(email: "", password: "") {
    // do something with user
} else {
    // error
}

// or

guard let user = SecurityService.loginWith(email: "", password: "") else {
    // error
    return
}

// do something with user
Run Code Online (Sandbox Code Playgroud)

  • @DougMead:当您不关心*为什么*或*如何*失败时,可选返回很好.错误处理系统适用于需要传达此类信息的情况. (2认同)

Mar*_*ean 1

为了添加这个问题的答案(五年后),有\xe2\x80\x99s一个专门的Result针对这种情况的类型。它可以在成功时返回您想要的类型,或者在失败时输入错误。

\n

它确实意味着重构一些代码以接受完成处理程序,然后枚举该回调中的结果:

\n\n
class SecurityService {\n    static func loginWith(email: String, password: String, completionHandler: @escaping (Result<User, SecurityError>) -> Void) {\n        // Body\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后在处理程序中:

\n
securityService.loginWith(email: email, password: password) { result in\n    switch result {\n    case .success(let user):\n        // Do something with user\n        print("Authenticated as \\(user.name)")\n    case .failure(let error):\n        // Do something with error\n        print(error.localizedDescription)\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n