【问题标题】:Save rethrowing function as a non-throwing closure将重新抛出函数保存为非抛出闭包
【发布时间】:2017-09-04 09:01:00
【问题描述】:

据我了解,rethrows 本质上是从一个声明/定义中创建两个函数,如下所示:

func f(_ c: () throws -> Void) rethrows { try c()}

// has the same effect as declaring two seperate functions, with the same name:

func g(_ c: () throws -> Void) throws { try c() }
func g(_ c: () -> Void) { c() }

如果我有一个重新抛出函数,比如f,有没有办法将它保存为“非抛出”形式的闭包?假设,像这样:

let x: (() -> Void) -> Void = f
// invalid conversion from throwing function of type '(() throws -> Void) throws -> ()' to non-throwing function type '(() -> Void) -> Void'

x{ print("test") } // "try" not necessary, because x can't throw

【问题讨论】:

  • let x: (() -> Void) -> Void = { f($0) } 算作解决方案吗?它不是同一个闭包,而是一个包装器。
  • @MartinR 我想是的,是的。我觉得奇怪的是没有(我知道)允许这种分配的类型关系
  • 您可能想知道编译器实际上只为rethrows 函数创建了一个重载——throws。在将它与不throw 的闭包一起应用的情况下,编译器会简单地忽略函数返回错误的可能性。因此,我怀疑没有简单的方法来获得不抛出的形式——闭包包装器可能是最好的解决方案。
  • @Hamish Hah,这就是我认为它会实现的方式。但遗憾的是没有自动机制来适应这种情况(例如自动引入额外的包装器)
  • @Alexander 是的,很遗憾:/ 在其他情况下,您确实希望编译器只为您编写一个 thunk,但目前并没有——另一个例子是mind 用于默认参数,例如func foo(_ i: Int = 3) {}; let bar: () -> Void = foo

标签: swift closures throw rethrow


【解决方案1】:

直到有人提出更好的解决方案:使用包装器

func f(_ c: () throws -> Void) rethrows { try c() }

let x: (() -> Void) -> Void = { f($0) }

【讨论】:

  • 我会推迟接受这个答案,直到更多人有机会看到这个问题
  • @Alexander:当然! – 顺便说一句,一个简单的赋值 let x = f 使 x 成为“仅抛出”闭包。显然只有函数可以用 rethrow 声明,而不是闭包。
  • 是的,我注意到了,这很奇怪。
猜你喜欢
  • 2017-12-04
  • 2021-06-08
  • 1970-01-01
  • 2019-06-15
  • 2019-08-30
  • 2021-10-08
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多