为异步函数定义Handler trait时出现Rust编译错误
解决异步Handler trait的Send安全编译错误
你的代码中,为异步函数类型实现Handler trait时,缺少对返回future的Send约束,导致编译报错。
原代码及错误
#[async_trait] trait Handler: Send + Sync + 'static { async fn handle(&self, req: Request<Body>) -> Result<Response<Body>, GenericError>; } #[async_trait] impl<F: Send + Sync + 'static, Fut> Handler for F where F: Fn(Request<Body>) -> Fut, Fut: Future<Output = Result<Response<Body>, GenericError>>, { async fn handle(&self, req: Request<Body>) -> Result<Response<Body>, GenericError> { self(req).await } }
编译错误:
future cannot be sent between threads safely required for the cast to the object type `dyn futures::Future<Output = Result<Response<Body>, Box<(dyn std::error::Error + Sync + std::marker::Send + 'static)>>> + std::marker::Send`rustc router.rs(21, 9): future is not `Send` as it awaits another future which is not `Send` router.rs(18, 63): consider further restricting this bound: ` + std::marker::Send`
解决方案
在Fut的约束中添加Send trait限定,修改后的代码如下:
#[async_trait] trait Handler: Send + Sync + 'static { async fn handle(&self, req: Request<Body>) -> Result<Response<Body>, GenericError>; } #[async_trait] impl<F: Send + Sync + 'static, Fut> Handler for F where F: Fn(Request<Body>) -> Fut, Fut: Future<Output = Result<Response<Body>, GenericError>> + Send, { async fn handle(&self, req: Request<Body>) -> Result<Response<Body>, GenericError> { self(req).await } }
原因说明
Handler trait本身要求实现者满足Send + Sync,意味着它可能在多线程环境中被调用和传递。async_trait宏会将异步方法的返回future包装成dyn Future + Send类型,因此必须保证F返回的Fut也实现了Send,才能满足跨线程安全传递的要求。错误提示已经明确建议添加+ std::marker::Send约束,按照提示补充即可解决问题。
内容的提问来源于stack exchange,提问作者Scalalang2
相关产品推荐
相关产品推荐

