Rust中async_trait异步trait的Future缺少Send标记编译错误解决
解决async_trait异步关联函数的Send约束缺失问题
问题重现
代码
#[async_trait] pub trait UserRepo { async fn init() -> Result<Self, AppError> ; } #[derive(Clone, Debug)] pub struct UserRepoImpl { pub collection: mongodb::Collection<User>, } #[async_trait] impl UserRepo for UserRepoImpl { pub async fn init() -> Result<Self, AppError> { let db = database::connection().await; let col: Collection<User> = db.collection("users"); Ok(UserRepoImpl{collection: col}) } }
错误信息(翻译后)
期望签名:`fn() -> Pin<Box<(dyn futures::Future<Output = Result<UserRepoImpl, AppError>> + std::marker::Send + 'async_trait)>>` 实际签名:`fn() -> Pin<Box<(dyn futures::Future<Output = Result<UserRepoImpl, AppError>> + 'async_trait)>>`
解决方案
错误核心是async_trait宏默认要求异步关联函数返回的Future携带Send约束,但当前代码签名未满足该要求。通过以下两步修复:
移除实现中
init函数的pub修饰符:
trait中定义的方法已默认公开,实现时重复声明pub会违反Rust可见性规则。给
trait添加Send约束:
可选两种方式:- 让
trait直接继承Send:#[async_trait] pub trait UserRepo: Send { async fn init() -> Result<Self, AppError>; } - 或在
init函数的where子句中约束Self: Send:#[async_trait] pub trait UserRepo { async fn init() -> Result<Self, AppError> where Self: Send; }
- 让
额外注意:需确保User类型实现Send(只要User的所有字段都是Send,会自动实现),因为mongodb::Collection<User>的Send特性依赖于User的Send实现。
修改后的完整代码示例:
#[async_trait] pub trait UserRepo: Send { async fn init() -> Result<Self, AppError>; } #[derive(Clone, Debug)] pub struct UserRepoImpl { pub collection: mongodb::Collection<User>, } #[async_trait] impl UserRepo for UserRepoImpl { async fn init() -> Result<Self, AppError> { let db = database::connection().await; let col: Collection<User> = db.collection("users"); Ok(UserRepoImpl{collection: col}) } }
内容的提问来源于stack exchange,提问作者user824624
相关产品推荐
相关产品推荐

