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

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

问题描述

在搜索了一些参考资料以弄清楚之后,-不幸的是-我找不到关于理解throwsrethrows 之间差异的有用且简单的描述.当试图理解我们应该如何使用它们时,这有点令人困惑.

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 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.
    • 同样适用于 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屋!

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