从存储的抛出函数中抛出错误
Throwing an error from a stored throwing function
我有一组抛出完成块处理程序:
typealias CompletionBlock = (MyType) throws -> Void
private var handlers: [CompletionBlock] = []
我希望以后能够召回它们并抛出这样的错误:
for handler in handlers {
handler(throw myError)
}
但是,这不起作用,因为它期望我将 MyType
传递给处理程序,而不是错误。我该怎么做?
您正试图改变存储闭包的行为,无论其输入如何都强制它抛出错误。你不能那样做。
您将 CompletionBlock
标记为 throws
的事实仅意味着闭包本身可能会抛出。但是,您不能强制它抛出,因为您只能将类型为 MyType
的输入参数传递给它。
此外,强制抛出闭包没有意义,因为无论如何您都需要处理从 call-site 抛出的错误。所以你可以简单地从调用站点抛出错误。
或者,如果您需要闭包本身来处理 error
,您应该更改闭包以接受 Result
并且在注入 .failure
的情况下,闭包本身可以扔.
typealias CompletionBlock = (Result<MyType, MyError>) throws -> Void
private var handlers: [CompletionBlock] = []
for handler in handlers {
handler(.failure(myError))
}
你的问题有点含糊,但我假设你的意思是你希望处理程序接受抛出函数的结果。这是可能的,我会展示如何,但这不是您想要的完全。
“抛出函数的结果”可以通过调用调用抛出函数的函数来表示:
typealias CompletionBlock = (() throws -> MyType) -> Void
按照您描述的方式抛出错误:
let result: () throws -> MyType = { throw MyError() }
for handler in handlers {
handler(result)
}
处理程序将如下所示:
func h(result: () throws -> MyType) {
do {
let myType = try result()
// ...
} catch {
// ...
}
}
但这不是一个很好的设计。最重要的是它多次执行 result
。相反,您想传递抛出函数的 Result
:
typealias CompletionBlock = (Result<MyType, Error>) -> Void
let f: () throws -> MyType = { throw MyError() }
let result = Result(catching: f)
for handler in handlers {
handler(result)
}
更常见的外观如下:
let result = Result {
// Do various operations that might throw
return value
}
您还可以使用 try result.get()
从 Result 转换回 throws。因此,您可以轻松地在 Result 和 throw 之间移动,随心所欲。结果最好用于存储。投掷最适合跟注。你可以两者兼得。
(当然,您还应该展望未来并探索用 async/await 替换完成处理程序,但有很多原因您可能不会立即这样做,因此 Result 将是一个重要的工具相当长一段时间。)
我有一组抛出完成块处理程序:
typealias CompletionBlock = (MyType) throws -> Void
private var handlers: [CompletionBlock] = []
我希望以后能够召回它们并抛出这样的错误:
for handler in handlers {
handler(throw myError)
}
但是,这不起作用,因为它期望我将 MyType
传递给处理程序,而不是错误。我该怎么做?
您正试图改变存储闭包的行为,无论其输入如何都强制它抛出错误。你不能那样做。
您将 CompletionBlock
标记为 throws
的事实仅意味着闭包本身可能会抛出。但是,您不能强制它抛出,因为您只能将类型为 MyType
的输入参数传递给它。
此外,强制抛出闭包没有意义,因为无论如何您都需要处理从 call-site 抛出的错误。所以你可以简单地从调用站点抛出错误。
或者,如果您需要闭包本身来处理 error
,您应该更改闭包以接受 Result
并且在注入 .failure
的情况下,闭包本身可以扔.
typealias CompletionBlock = (Result<MyType, MyError>) throws -> Void
private var handlers: [CompletionBlock] = []
for handler in handlers {
handler(.failure(myError))
}
你的问题有点含糊,但我假设你的意思是你希望处理程序接受抛出函数的结果。这是可能的,我会展示如何,但这不是您想要的完全。
“抛出函数的结果”可以通过调用调用抛出函数的函数来表示:
typealias CompletionBlock = (() throws -> MyType) -> Void
按照您描述的方式抛出错误:
let result: () throws -> MyType = { throw MyError() }
for handler in handlers {
handler(result)
}
处理程序将如下所示:
func h(result: () throws -> MyType) {
do {
let myType = try result()
// ...
} catch {
// ...
}
}
但这不是一个很好的设计。最重要的是它多次执行 result
。相反,您想传递抛出函数的 Result
:
typealias CompletionBlock = (Result<MyType, Error>) -> Void
let f: () throws -> MyType = { throw MyError() }
let result = Result(catching: f)
for handler in handlers {
handler(result)
}
更常见的外观如下:
let result = Result {
// Do various operations that might throw
return value
}
您还可以使用 try result.get()
从 Result 转换回 throws。因此,您可以轻松地在 Result 和 throw 之间移动,随心所欲。结果最好用于存储。投掷最适合跟注。你可以两者兼得。
(当然,您还应该展望未来并探索用 async/await 替换完成处理程序,但有很多原因您可能不会立即这样做,因此 Result 将是一个重要的工具相当长一段时间。)