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

使用async块与ServiceFn实现tower::Layer遇类型推导错误求助

解决Tower layer_fn中async块的类型推导错误

方案一:使用泛型约束明确Service类型

将layer_fn的闭包参数改为泛型类型并添加Service约束,让编译器能明确追踪请求、响应和错误类型:

use std::convert::Infallible;
use tower::Service;

tower::ServiceBuilder::new()
    .layer_fn(|mut service: S| {
        tower::service_fn(move |request: String| {
            async move {
                let response: Result<String, Infallible> = service.call(request).await;
                // 这里可以添加需要await的业务逻辑
                response
            }
        })
    })
    .service_fn(|request: String| {
        async move {
            Ok::<_, Infallible>(request)
        }
    });

原理:通过泛型约束S: Service<String, Response = String, Error = Infallible>,直接明确了下游Service的请求类型、响应类型和错误类型,编译器可以在async块中准确推导service.call(request)返回的Future类型,解决类型推断失败的问题。


方案二:用Turbofish明确call方法的类型参数

如果需要保留ServiceFn<_>的标注,可以通过Turbofish语法直接指定call方法的类型参数:

use std::convert::Infallible;
use tower::util::ServiceFn;

tower::ServiceBuilder::new()
    .layer_fn(|mut service: ServiceFn<_>| {
        tower::service_fn(move |request| {
            async move {
                // 用Turbofish指定请求类型为String,帮助编译器推导返回类型
                let response = service.call::<String, _, _>(request).await;
                // 业务逻辑处理
                response
            }
        })
    })
    .service_fn(|request: String| {
        async move {
            Ok::<_, Infallible>(request)
        }
    });

原理:Service::call是一个带多个类型参数的方法,在async块中编译器无法自动推导这些参数,通过turbofish语法明确指定请求类型为String,可以让编译器反向推导出返回的Future和结果类型。


错误原因分析

原代码中直接将参数标注为ServiceFn<_>,占位符类型_在async块中无法被编译器正确解析——因为await会引入Future类型,而编译器需要明确的类型信息来构建这个Future。通过上述两种方式给编译器提供足够的类型线索,就能解决E0698类型推断错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 03:17:04