Swift中的抛出和反馈有什么区别?
在搜索了一些参考文献以找出它之后,我很难找到有用的简单描述来了解throws
和rethrows
之间的区别。试图了解我们应该如何使用它时,这有点令人困惑。Swift中的抛出和反馈有什么区别?
我会告诉你我有种熟悉的 - 默认throws
用最简单的传播错误的形式,如下所示:
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")
}
}
到目前为止好,但问题出现时:
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
时,我们应遵循什么逻辑?
从"Declarations"在斯威夫特书:
重新抛出函数和方法
一个函数或方法可以与
rethrows
关键字 声明表明,它抛出一个错误只有一个它的功能 参数会引发错误。这些功能和方法被称为 重新抛光功能和重新抛光方法。回滚函数和 方法必须至少有一个抛出函数参数。
一个典型的例子是map
方法:
public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
如果map
被称为具有非抛变换,它不会引发 错误本身,并且可以被称为无try
:
// Example 1:
let a = [1, 2, 3]
func f1(n: Int) -> Int {
return n * n
}
let a1 = a.map(f1)
但是,如果map
被调用了投掷闭包,那么它本身可以抛出 d必须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
那么你就 甚至已经在例1try
称呼它, 这是“不方便”和腌代码不必要。 - 如果
map
被声明没有throws/rethrows
那么你不能用 用例2中的抛出闭包来调用它。
同样是从雨燕标准库 内搭功能参数的其他方法一样:filter()
,index(where:)
,forEach()
和许多许多。
在你的情况,
func throwCustomError(function:(String) throws ->()) throws
表示功能,可以抛出一个错误,即使调用 非投掷的说法,而
func rethrowCustomError(function:(String) throws ->()) rethrows
表示这将引发错误的函数只有在调用 的投掷参数时才有效。
粗略地讲,rethrows
是不“靠自己”扔 错误的功能,但只有“前进”的错误,从它们的功能 参数。
只是添加了一些与马丁的答案。具有与投掷功能相同签名的非投掷功能被认为是投掷功能的sub-type
。这就是为什么rethrows可以决定它是哪一个,并且只有当func param也抛出时才需要try
,但仍然接受不抛出的相同函数签名。当func参数抛出时,只需要使用do try块就是一种方便的方法,但函数中的其他代码不会引发错误。
很好的回答。谢谢。 – Darko
最后一句话是金色的! – Klaas
所以我想总结一下,当你*可能会抛出时'重新抛出'。当你想**限制为总是投掷时投掷''' – Honey