【问题标题】:Expression type '()' is ambiguous without more context when using generic closure使用泛型闭包时,表达式类型“()”在没有更多上下文的情况下是模棱两可的
【发布时间】:2019-05-02 13:15:10
【问题描述】:

我在尝试创建自己的通用闭包时遇到此错误。

我找不到这个问题的任何潜在解决方案。

完整代码:

func customRequest<T : Codable>(_ target: Api, whenSuccess: @escaping CustomCompletion<T>, whenError: @escaping (String) -> Void) {
        super.request(target, callbackQueue: .none, progress: .none, completion: { result in
            switch result {
            case let .success(response):
                if let data = try? JSONDecoder().decode(BaseAPIModel<T>.self, from: response.data) {
                    if data.isValid(), let result = data.result {
                        whenSuccess(result)
                    } else {
                        whenError(data.toErrorReadableString())
                    }
                } else {
                    whenError("Something had gone wrong. Please try again.")
                }
            case let .failure(error):
                if let response = error.response, let data = try? JSONDecoder().decode(BasicAPIModel.self, from: response.data) {
                    whenError(data.toErrorReadableString())
                } else {
                    whenError("Something had gone wrong. Please try again.")
                }
            }
        })
    }

fileprivate func getLogo() {
        // Error come from this line
        ApiProvider().customRequest(Api.prefetchLogo, whenSuccess: { _ in

        }, whenError: { (error) in

        })
    }

【问题讨论】:

  • 这取决于ApiCustomCompletion 是什么。我建议您在所有内容上都提供明确的类型,直到错误更清楚为止。例如,与其为whenSuccess 传递闭包,不如显式创建一个CustomCompletion 变量并传递它(whenError 相同)。通过将事物分配给明确类型的变量,编译器可以更轻松地告诉您哪里出错了。
  • Api 是一个枚举,CustomCompletion 指的是public typealias CustomCompletion&lt;T&gt; = (_ result: T) -&gt; Void

标签: swift generics


【解决方案1】:

编译器无法确定T 是什么类型的CustomCompletion&lt;T&gt; 这段代码。有两种方式来提供它。

将其添加到customRequest的传递参数中,例如作为fetching参数:

func customRequest<T : Codable>(_ target: Api, fetching: T.Type, 
                                whenSuccess: @escaping CustomCompletion<T>, 
                                whenError: @escaping (String) -> Void) {

那么它会被称为:

ApiProvider().customRequest(Api.prefetchLogo, fetching: Something.self, ...

或者给闭包参数加一个类型:

ApiProvider().customRequest(Api.prefetchLogo, whenSuccess: { (_: Something) in

虽然你不关心返回值是什么,但编译器仍然需要生成代码来解码它,并且它需要以某种方式知道它的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多