Swift 中的 throws 和 rethrows 有什么区别? [英] What are the differences between throws and rethrows in Swift?
问题描述
在搜索了一些参考资料以弄清楚之后,-不幸的是-我找不到关于理解throws
和rethrows
之间差异的有用且简单的描述.当试图理解我们应该如何使用它们时,这有点令人困惑.
After searching for some references to figure it out, -unfortunately- I could not find useful -and simple- description about understanding the differences between throws
and rethrows
. It is kind of confusing when try to understand how we should use them.
我想提一下,我有点熟悉 -default- throws
及其最简单的传播错误形式,如下所示:
I would mention that I am kind of familiar with the -default- throws
with its simplest form for propagating an error, as follows:
enum CustomError: Error {
case potato
case tomato
}
func throwCustomError(_ string: String) throws {
if string.lowercased().trimmingCharacters(in: .whitespaces) == "potato" {
throw CustomError.potato
}
if string.lowercased().trimmingCharacters(in: .whitespaces) == "tomato" {
throw CustomError.tomato
}
}
do {
try throwCustomError("potato")
} catch let error as CustomError {
switch error {
case .potato:
print("potatos catched") // potatos catched
case .tomato:
print("tomato catched")
}
}
到目前为止一切顺利,但问题出现在:
So far so good, but the problem arises when:
func throwCustomError(function:(String) throws -> ()) throws {
try function("throws string")
}
func rethrowCustomError(function:(String) throws -> ()) rethrows {
try function("rethrows string")
}
rethrowCustomError { string in
print(string) // rethrows string
}
try throwCustomError { string in
print(string) // throws string
}
目前我所知道的是,当调用一个 throws
的函数时,它必须由 try
处理,这与 rethrows
不同.所以呢?!在决定使用 throws
还是 rethrows
时,我们应该遵循什么逻辑?
what I know so far is when calling a function that throws
it has to be handled by a try
, unlike the rethrows
. So what?! What is logic that we should follow when deciding to use throws
or rethrows
?
推荐答案
来自 "声明" 在 Swift 书中:
From "Declarations" in the Swift book:
重新抛出函数和方法
一个函数或方法可以用 rethrows
关键字来声明表明只有当它的功能之一时它才会抛出错误参数抛出错误.这些函数和方法被称为重新抛出函数和重新抛出方法.重新抛出函数和方法必须至少有一个抛出函数参数.
A function or method can be declared with the rethrows
keyword to
indicate that it throws an error only if one of it’s function
parameters throws an error. These functions and methods are known as
rethrowing functions and rethrowing methods. Rethrowing functions and
methods must have at least one throwing function parameter.
一个典型的例子是map
方法:
A typical example is the map
method:
public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
如果 map
被非抛出转换调用,它不会抛出一个错误本身,可以在没有 try
的情况下调用:
If map
is called with a non-throwing transform, it does not throw
an error itself and can be called without try
:
// Example 1:
let a = [1, 2, 3]
func f1(n: Int) -> Int {
return n * n
}
let a1 = a.map(f1)
但是如果 map
被一个抛出闭包调用,那么它本身可以抛出并且必须使用 try
调用:
But if map
is called with a throwing closure then itself can throw
and must be called with try
:
// Example 2:
let a = [1, 2, 3]
enum CustomError: Error {
case illegalArgument
}
func f2(n: Int) throws -> Int {
guard n >= 0 else {
throw CustomError.illegalArgument
}
return n*n
}
do {
let a2 = try a.map(f2)
} catch {
// ...
}
- 如果
map
被声明为throws
而不是rethrows
那么你会即使在示例 1 中,也必须使用try
调用它,这是不方便的"并且不必要地膨胀代码. - 如果
map
是在没有throws/rethrows
的情况下声明的,那么你不能使用抛出闭包调用它,如示例 2 中所示. - If
map
were declared asthrows
instead ofrethrows
then you would have to call it withtry
even in example 1, which is "inconvenient" and bloats the code unnecessary. - If
map
were declared withoutthrows/rethrows
then you could not call it with a throwing closure as in example 2.
同样适用于 Swift 标准库中的其他方法接受函数参数:filter()
、index(where:)
、forEach()
等等.
The same is true for other methods from the Swift Standard Library
which take function parameters: filter()
, index(where:)
, forEach()
and many many more.
就你而言,
func throwCustomError(function:(String) throws -> ()) throws
表示一个可以抛出错误的函数,即使调用一个非抛出的参数,而
denotes a function which can throw an error, even if called with a non-throwing argument, whereas
func rethrowCustomError(function:(String) throws -> ()) rethrows
表示一个函数,该函数仅在调用时抛出错误抛出论据.
denotes a function which throws an error only if called with a throwing argument.
粗略地说,rethrows
用于不抛出的函数错误自行",但仅转发"来自其功能的错误参数.
Roughly speaking, rethrows
is for functions which do not throw
errors "on their own", but only "forward" errors from their function
parameters.
这篇关于Swift 中的 throws 和 rethrows 有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!