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

Swift 4:使用抛出型完成闭包处理错误时传参报错,如何修复?

修复抛出型闭包的编译器错误

首先得说清楚你遇到的问题根源:你定义的completion是一个不需要任何参数、但执行时可能抛出错误的闭包(类型是() throws -> Void)。但你现在调用它的时候,传了一个{ throw RefreshTokenError.notFounded }的闭包作为参数——这完全不符合completion的参数要求,它根本不需要参数,所以编译器才会报错“Argument passed to call that takes no arguments”。

下面给你三种可行的修复方案,你可以根据自己的需求选择:

方案1:改用接收错误的闭包(最常用的异步错误处理方式)

这种方式把completion改成接收可选Error参数,有错误就传错误实例,没错误传nil,逻辑清晰且适合异步场景:

private func executeRefreshTokenRequest(_ completion: @escaping (Error?) -> Void) { 
    DispatchQueue.global(qos: .userInitiated).sync { 
        guard let refreshToken = currentRefreshToken else { 
            completion(RefreshTokenError.notFounded) // 直接传入错误
            return // 记得加return,避免后续代码继续执行
        } 
        // 这里写你的refreshTokenUrlRequest逻辑...
        // 请求成功时调用 completion(nil)
        // 请求失败时调用 completion(对应的错误实例)
    }
}

// 调用示例
executeRefreshTokenRequest { error in
    if let error = error {
        print("刷新Token失败:\(error.localizedDescription)")
    } else {
        print("Token刷新成功")
    }
}

方案2:使用Swift的Result类型(现代推荐写法)

Result类型可以明确区分成功和失败状态,代码可读性更强:

private func executeRefreshTokenRequest(_ completion: @escaping (Result<Void, Error>) -> Void) { 
    DispatchQueue.global(qos: .userInitiated).sync { 
        guard let refreshToken = currentRefreshToken else { 
            completion(.failure(RefreshTokenError.notFounded))
            return
        } 
        // 后续的refreshTokenUrlRequest逻辑...
        // 成功时调用 completion(.success(()))
        // 失败时调用 completion(.failure(请求错误))
    }
}

// 调用示例
executeRefreshTokenRequest { result in
    switch result {
    case .success:
        print("Token刷新成功")
    case .failure(let error):
        print("刷新失败:\(error)")
    }
}

方案3:坚持使用抛出型闭包(仅适合同步场景)

如果你一定要保留() throws -> Void类型的completion,那得调整调用逻辑——因为这种闭包的含义是「闭包自身执行时可能抛出错误」,而不是「接收一个错误参数」。你需要直接在合适的上下文抛出错误,并且用try调用completion:

private func executeRefreshTokenRequest(_ completion: @escaping () throws -> Void) throws { 
    try DispatchQueue.global(qos: .userInitiated).sync { 
        guard let refreshToken = currentRefreshToken else { 
            throw RefreshTokenError.notFounded // 直接抛出错误
        } 
        // 后续请求逻辑...
        try completion() // 成功时执行completion
    }
}

// 调用示例
do {
    try executeRefreshTokenRequest {
        print("Token刷新成功")
    }
} catch {
    print("刷新失败:\(error)")
}

⚠️ 注意:这种抛出型的写法在异步场景下(比如用async代替sync)会有问题,因为抛出的错误无法跨线程传递,所以更推荐前两种方案。

内容的提问来源于stack exchange,提问作者Drugan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:23:36