如何从无返回值函数/闭包中返回闭包所需的类型?
问题分析与解决方案
你的代码报错核心原因:test函数要求传入的闭包必须返回Bool类型,但当前传给test的闭包中,最后一行是调用toDo函数——而toDo的返回类型是()(无返回值),同时toDo是通过回调传递结果的异步风格函数,无法直接在同步闭包里返回它的结果。
以下是几种可行解决方案,可根据业务场景选择:
方案一:将toDo改为同步返回结果(推荐,若无需异步)
如果toDo不需要异步执行,直接让它返回Bool,就能和test的闭包要求匹配:
func test(bool: @escaping () -> Bool) { print(bool()) } // 修改toDo为同步返回Bool func toDo() -> Bool { return Bool.random() } func callTest() { // 简化写法:直接传递函数引用 test(bool: toDo) // 或者用闭包写法: // test(bool: { // return toDo() // }) }
方案二:适配异步逻辑,修改test为回调式接口(推荐异步场景)
如果toDo必须保留异步回调的设计,那test也需要改成支持异步结果的接口,这是Swift异步编程的标准做法:
// 修改test为接受回调,直接传递toDo的结果 func test(completion: @escaping (Bool) -> Void) { toDo(value: completion) } func toDo(value: @escaping (Bool) -> Void) { value(Bool.random()) // 若实际是异步操作,比如后台线程执行: // DispatchQueue.global().async { // value(Bool.random()) // } } func callTest() { test { result in print(result) } }
方案三:用信号量强制同步(不推荐,易阻塞线程)
如果必须保留原test的同步接口,只能用DispatchSemaphore阻塞线程等待异步结果,但这种方式可能导致主线程卡顿甚至死锁,仅作为临时兼容方案:
func test(bool: @escaping () -> Bool) { print(bool()) } func toDo(value: @escaping (Bool) -> Void) { // 模拟异步操作 DispatchQueue.global().async { value(Bool.random()) } } func callTest() { test(bool: { let semaphore = DispatchSemaphore(value: 0) var finalResult = false toDo(value: { inComingValue in finalResult = inComingValue semaphore.signal() // 通知信号量:结果已获取 }) semaphore.wait() // 阻塞线程,直到收到信号 return finalResult }) }
内容的提问来源于stack exchange,提问作者swiftPunk
相关产品推荐
相关产品推荐

