You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift:能否从异步抛出函数返回异步抛出函数,无需try! await?

Swift异步抛出函数转发的正确写法

核心结论

  • 绝对不要用try! await:这会直接忽略函数抛出的错误,一旦发生错误会导致程序崩溃,完全不是最佳实践。
  • 转发异步抛出函数的调用结果时,必须用try await等待任务完成并正确传递错误。

错误写法分析

  1. 直接返回异步函数调用:
func bar() async throws -> Bool {
  return foo() // 报错:Call can throw but is not marked with 'try'
}

原因:foo()是async throws类型的函数,调用它需要await等待异步任务完成,同时必须用try处理或传递抛出的错误,不能直接返回未执行的异步任务。

  1. 返回类型不匹配的函数调用结果:
func bar() async throws -> (() async throws -> Bool) {
    return foo() // 报错:Cannot convert return expression of type 'Bool' to return type '() async throws -> Bool'
}

原因:foo()是调用后的异步任务结果(最终类型为Bool),而返回类型要求的是未执行的异步函数,这里应返回函数本身foo而非调用结果。但这种写法对带参数的函数(如baz(_ some: Int))不适用,因为baz(12)是调用后的结果,不是函数本身。

正确的转发写法

1. 直接转发调用结果(最常用场景)

如果bar()的目的是调用foo()并返回其结果,同时向上传递错误,正确写法是:

func foo() async throws -> Bool {
    return true
}

func bar() async throws -> Bool {
    return try await foo()
}

这样bar()会等待foo()执行完成,若foo()抛出错误,bar()会将错误继续抛出给上层调用者处理,既安全又简洁。

2. 返回包装后的异步函数(针对带参数的场景)

如果需要bar()返回一个可执行的异步函数(比如包装baz(12)的调用),可以用闭包封装:

func baz(_ some: Int) async throws -> Bool {
    return true
}

func bar() async throws -> (() async throws -> Bool) {
    return { try await baz(12) }
}

返回的闭包会在被调用时执行baz(12),并正确处理异步和错误逻辑。

总结

  • 普通的调用转发用try await即可,这是安全且符合Swift错误处理规范的最佳实践。
  • 若需要返回异步函数而非调用结果,用闭包封装带参数的函数调用即可解决类型不匹配问题。

内容的提问来源于stack exchange,提问作者I'm Joe Too

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:01:09