无法将类型 '(_) -> Observable<Response>' 的值转换为预期的参数类型 '([_]) -> _'

Posted

技术标签:

【中文标题】无法将类型 \'(_) -> Observable<Response>\' 的值转换为预期的参数类型 \'([_]) -> _\'【英文标题】:Cannot convert value of type '(_) -> Observable<Response>' to expected argument type '([_]) -> _'无法将类型 '(_) -> Observable<Response>' 的值转换为预期的参数类型 '([_]) -> _' 【发布时间】:2016-12-03 02:02:15 【问题描述】:

我遇到了以下错误:

Cannot convert value of type '(_) -> Observable<Response>' 
to expected argument type '([_]) -> _'

当我尝试编译时:

func request(_ token: MyAPI) -> Observable<Moya.Response> 
    switch (target.requiresCSRF, target.requiresOAuth) 
    case (false, false): return actualRequest 
    case (true, false): return CSRFTokenRequest().flatMap  _ in actualRequest 
    case (false, true): return OAuthTokenRequest().flatMap  _ in actualRequest 
    case (true, true): return Observable.zip([CSRFTokenRequest(), OAuthTokenRequest()])  _ in actualRequest 
     

actualRequest 的类型为 Observable&lt;Response&gt; CSRFTokenRequest 和 OAuthTokenRequest 的类型都是 Observable&lt;String?&gt;

我尝试在 OAuthTokenRequest 之前运行 CSRFTokenRequest,然后再运行实际请求。

以下解决了问题...但我不确定这是否是正确的方法...

return RequiresCSRFTokenRequest().flatMap _ in
            self.RequiresAuthenticationRequest().flatMap _ in actualRequest
        



fileprivate extension Networking

    func RequiresAuthenticationRequest() -> Observable<String> 

        /// This has 3 cases

        // 0. token is not present, error out
        // 1. token is not expired, return token
        // 2. token is expired, needs refresh

        guard let jwt = AuthManager.shared.accessToken else
            return .just("Error!! No access tokens")
        

        // If access token is valid
        if AuthManager.shared.expiredAccessToken == false

            return .just(jwt)

        else

            return request(.refreshAccessToken(refreshToken: AuthManager.shared.refreshTokenWithBearer!))
                .filterSuccessfulStatusCodes()
                .mapObject(type: UserAuthenticationTokens.self)
                .do(onNext: 
                    $0.save())
                .map (token) -> String in
                    // Get new access token that was just saved
                    return AuthManager.shared.accessToken!
            
        

    


    func RequiresCSRFTokenRequest() -> Observable<String> 

        // Always get a new csrf token
        return request(.getCSRF())
            .filterSuccessfulStatusCodes()
            .mapObject(type: CSRFToken.self)
            .do(onNext: 
                $0.save()
            ).map (token) -> String in
                return AuthManager.shared.csrf_token!
            
    


谢谢!

【问题讨论】:

所有这些表达式的返回类型是什么? 它们应该是 Observable actualRequest 是什么?我想它返回一个 `Observable 不是吗?请分享更多关于你的类型,没有更多信息很难帮助你 当你在你的函数中只返回actualRequestObservable时会发生什么?(删除其他所有内容只是return actualRequest 它构建良好,无需切换追逐,只需返回实际请求 【参考方案1】:

据我所知,如果您仔细查看 switch 语句中的最后一个案例,以及 CSRFTokenRequest()OAuthTokenRequest() 两个函数都返回 Observables&lt;String?&gt; 的事实,那么您正在创建一个新的 @987654325 @ 等待两者都发出。

zip 为您发出两个 Observable,在您的情况下,您使用 _ return actualRequest 省略了这两个。 但是当你返回函数 actualRequest 时要小心,它期待另一件事,所以这里的重点是将 Observable&lt;A&gt; 转换为 Observable&lt;B&gt;

为此,您将需要像以前一样使用flatMap 函数,而在最后一个案例中您错过了它。

让我们看看例子:

Observable.zip(Observable.just(1), Observable.just("!"))  (a, b) in
   return (a,b)

.flatMap   _ in return Observable.just(4.0) 
.subscribe(onNext:  value in
    print(value)
)
.addDisposableTo(disposeBag)

在上面的例子中,我省略了Observable&lt;Int&gt;Observable&lt;String&gt;这两个值来创建一个新的Observable&lt;Double&gt;

在你的情况下,你应该这样做:

return Observable.zip(CSRFTokenRequest(), OAuthTokenRequest()).flatMap  _ in actualRequest 

希望对你有帮助

【讨论】:

我用解决问题的方法更新了我的帖子......但我不确定这是否是平面映射的正确方法......你有什么建议? @user805981 不,完全不建议对 Observables 进行嵌套调用,您应该使用 flatMap 那样的链接,请参阅我的更新答案 Cannot convert value of type 'Observable&lt;String?&gt;' (aka 'Observable&lt;Optional&lt;String&gt;&gt;') to expected argument type '([_]) throws -&gt; _' 现在使用你的方法给了我以下...是否必须为 Observables 进行某种类型的转换? 是的,您确实必须在某些时候进行投射,但这很奇怪,因为您忽略了不应该有必要的结果 你建议我做什么?我看了一下 Observable.zip 返回类型,它看起来像是 Observable&lt;Observable&lt;Response&gt;&gt; 与函数返回类型不符...

以上是关于无法将类型 '(_) -> Observable<Response>' 的值转换为预期的参数类型 '([_]) -> _'的主要内容,如果未能解决你的问题,请参考以下文章

无法将类型 '(_) -> Observable<Response>' 的值转换为预期的参数类型 '([_]) -> _'

错误:无法将类型“(_)->()”的值转换为预期的参数类型“(()-> Void)?”

无法将类型“(_) -> ()”的值转换为预期的参数类型“(() -> Void)?”

Alamofire:错误:无法将“结果<_,_>”类型的值分配给“结果”类型

无法将 Promise (_,_) -> DataRequest 类型的返回表达式转换为返回类型 Promise<DataResponse,AnyObject>>

firebase swift 3 转换:无法将类型“(_)->()”的值转换为预期的参数类型“((错误)-> Void)?