此刻,我实际上正在尝试快速地进行一些代码逻辑训练,我想知道从init中抛出错误的正确方法是什么?
因此,流程是Controller在初始化Model要求我的sql管理器创建帐户时要求创建帐户,并且此方法从闭包中返回结果。
但是感觉有些不对劲,我应该只使用包含我的两个Int的sql管理器的返回值吗?和错误? ?
init(_ username: String, _ password: String) throws {
self.id = 0
self.username = username
self.password = password
var toThrow: Error? = nil
// Register in database
userManager.create(self) { (id: Int?, err: Error?) in
Thread.sleep(forTimeInterval: 10)
if let error = err {
// Register in database goes wrong
debugPrint("Handle error from user creation...")
toThrow = error
} else {
// There is no id and no error ?
guard let _ = id else { return }
self.id = id!
}
}
if let error = toThrow {
throw error
}
}
答案 0 :(得分:0)
如果您使用的是Swift 5,则可以研究使用Result并像这样定义闭包
(id: Int) -> Result<Int, Error>
并将代码更改为
userManager.create(self) { (id: Int?) -> Result<Int, Error> in
Thread.sleep(forTimeInterval: 10)
if let error = err {
// Register in database goes wrong
debugPrint("Handle error from user creation...")
return .failure(error)
} else {
// There is no id and no error ?
guard let _ = id else { return }
return .success(id)
}
}
如果您对Db类有自己的错误枚举,例如
enum DbError {
case create
case update
//...
}
然后您可以在闭包声明中使用该类型
(id: Int?) -> Result<Int, DbError>
并为此操作返回特定错误
return .failure(.create)
请注意,我尚未对此进行编译,因此请考虑一个示例
答案 1 :(得分:0)
这是人们想要看的解决方案:
@IBAction func didPressRegister() {
guard let username = usernameField.text else { return }
guard let password = passwordField.text else { return }
let user = UserModel(username, password)
userManager.create(user) { result in
switch(result) {
case .failure(let error):
// TODO: UIAlert
debugPrint(error)
case .success(let int):
// TODO: Generate user token and redirect main
debugPrint(int)
}
}
}
// TODO
public func create(_ user: UserModel, _ complete: @escaping (Result<Int, Error>) -> ()) {
debugPrint("Requested to create the user... \(user)")
complete(.failure(toThrow.ACCOUNT_ERROR))
}