Swift中的投掷和推翻有什么区别? [英] What are the differences between throws and rethrows in Swift?

查看:336
本文介绍了Swift中的投掷和推翻有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在搜索一些参考文献后,不幸的是,我找不到有用的和简单的描述了解 throws 和<$ c $之间的差异C>重新抛出。当尝试了解我们应该如何使用它时,这很混乱。



我会提到我很熟悉-default- 抛出以其最简单的形式传播错误,如下所示:

 枚举CustomError:错误{
case potato
case tomato
}

func throwCustomError(_ string:String)throws {
如果string.lowercased()。修剪字符(in:。空白)==potato{
throw CustomError.potato
}

如果string.lowercased()。修剪字符(in:.whitespaces)==tomato{
throw CustomError.tomato
}
}

do {
try throwCustomError(potato)
}将let error作为CustomError {
开关错误{
case .potato:
print(potatos catched)// potatos catched
case .tomato:
print(tomato catched)
}
}

到目前为止这么好,b当以下情况出现问题:

  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
}

尝试throwCustomError {string in
print(string)// throws string
}

到目前为止,我所知道的是调用 throws 的函数时,它必须由 try 处理,不同于 rethrows 。所以呢?!决定使用 throws rethrows

解决方案

声明


重新运行函数和方法 / p>

可以使用 rethrows 关键字声明为
的函数或方法表示仅引发错误如果它的一个函数
参数抛出一个错误。这些功能和方法称为
重新启动函数重新抛出方法。 Rethrowing函数和
方法必须至少有一个抛出函数参数。


一个典型的例子是 map 方法:

  public func map< T(_ transform:(Element)throws  - > T)rethrows  - > [T] 

如果地图被调用一个非投掷变换,它不会抛出
一个错误本身,可以调用没有尝试

  //示例1:

let a = [1,2,3]

func f1(n:Int) - > Int {
return n * n
}

let a1 = a.map(f1)

但是如果映射被抛出一个封闭,那么本身就可以抛出
,并且必须使用尝试

  //示例2:

让一个= [1,2,3]
枚举CustomError:错误{
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 {
// ...
}




  • 如果映射被声明为 throws 而不是 rethrows 然后你将
    必须用尝试调用它在示例1中,
    这是不方便,并且不需要增加代码。

  • 如果映射被声明为没有 throws / rethrows 那么你不能
    用一个抛出的关闭调用它,如例2所示。



Swift标准库中的其他方法也是如此b $ b可以使用函数参数: filter() index(where:) forEach()等等。



在您的情况下,

  func throwCustomError(function:(String)throws  - >())throws 



即使使用
a非抛出参数调用,也可以引发错误的功能,而

  func rethrowCustomError(function:(String)throws  - >())rethrows 

表示一个函数,只有在调用
抛出参数时才会出错。



大致来说, rethrows 不要抛出
错误自己,而只是fo rward错误从他们的功能
参数。


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.

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
}

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?

解决方案

From "Declarations" in the Swift book:

Rethrowing Functions and Methods

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.

A typical example is the map method:

public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]

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)

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 {
    // ...
}

  • If map were declared as throws instead of rethrows then you would have to call it with try even in example 1, which is "inconvenient" and bloats the code unnecessary.
  • If map were declared without throws/rethrows then you could not call it with a throwing closure as in example 2.

The same is true for other methods from the Swift Standard Library which take function parameters: filter(), index(where:), forEach() and many many more.

In your case,

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.

Roughly speaking, rethrows is for functions which do not throw errors "on their own", but only "forward" errors from their function parameters.

这篇关于Swift中的投掷和推翻有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆