我正在尝试Result使用 Foundation for Swift 5 中的内置 Result 类型创建一个具有自定义错误类型的变量,但我无法让类型系统理解我想要抛出的错误类型。
下面的代码不能编译。
import Foundation
enum CustomError: String, Error {
case somethingBadHappened
}
struct Model {
let value: Int
}
class Request {
func execute(number: Int, completion: @escaping (Result<Model, CustomError>) -> Void) {
let result = Result { () throws -> Model in
if (number < 20) {
throw CustomError.somethingBadHappened
} else {
return Model(value: number)
}
}
// compiler complains here about: Cannot convert value of type 'Result<Model, Error>' to expected argument type 'Result<Model, CustomError>'
completion(result)
}
}
let request = Request()
request.execute(number: 19) { result in
switch result {
case .success(let value): print("Succeded with \(value)")
case .failure(let error): print("Failed with \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
将完成闭包的签名更改为completion: @escaping (Result<Model, Error>) -> Void有效,但随后我没有使用自定义错误类型。
如何让类型系统理解我想使用自定义错误类型?
很抱歉给出第二个答案,但需要对 fphilipe 的答案进行纠正。
您可以使用init(catching:)形成 Result 并将其作为Result<Model, CustomError>. 那mapError是为了什么!像这样:
enum CustomError: String, Error {
case somethingBadHappened
}
struct Model {
let value: Int
}
class Request {
func execute(number: Int, completion: @escaping (Result<Model, CustomError>) -> Void) {
let result = Result { () throws -> Model in
if (number < 20) {
throw NSError()
} else {
return Model(value: number)
}
}.mapError { err in
return CustomError.somethingBadHappened
}
completion(result)
}
}
Run Code Online (Sandbox Code Playgroud)
我必须抛出一些东西才能形成初始Result<Model, Error>,所以我只是抛出一个 NSError 作为一种占位符。但随后mapError出现并将其转换为Result<Model, CustomError>. 的力量mapError在于它只改变发生故障时发生的事情。
因此我们能够保持代码的原始形式。
只需手动创建Result:
let result: Result<Model, CustomError>
if (number < 20) {
result = .failure(.somethingBadHappened)
} else {
result = .success(Model(value: number))
}
completion(result)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3554 次 |
| 最近记录: |