如何在带生命周期参数的泛型场景下使用Rust的async_trait?
问题根源
async_trait宏底层会将标记的async方法转换为返回Pin<Box<dyn Future<Output = 方法返回值> + Send + 'async_trait>>的同步方法,其中'async_trait是宏自动生成的生命周期,默认要求所有输入参数的生命周期不短于'async_trait。你定义的原始trait没有声明该约束,因此当实现中泛型T携带生命周期'a时,宏自动添加的'a: 'async_trait约束会被Rust编译器判定为实现比trait要求更严格,触发E0276错误。
解决方案
在trait的async_trait属性中显式添加约束,要求所有实现的泛型T满足T: 'async_trait,让trait层面就携带该约束,实现时就不会出现额外约束的报错。修改后的可编译代码如下:
use async_trait::async_trait; struct MyLifetimeType<'a> { s: &'a mut String, } // 新增bound约束,要求T的生命周期不短于宏生成的'async_trait #[async_trait(bound = "T: 'async_trait")] trait MyTrait<T> { async fn handle(t: T); } struct MyImpl; #[async_trait] impl<'a> MyTrait<MyLifetimeType<'a>> for MyImpl { async fn handle(t: MyLifetimeType<'a>) { t.s.push_str("hi"); } }
该方案完全适配你的业务场景:传递的RwLockReadGuard、RwLockWriteGuard自带的锁生命周期会被T: 'async_trait约束自动覆盖,只要handle返回的Future不会比守卫本身生命周期更长,就可以正常在方法内修改守卫指向的内容,不需要额外调整业务逻辑。
内容的提问来源于stack exchange,提问作者mwlon
相关产品推荐
相关产品推荐

