首页 > 解决方案 > 如何将 rust async_trait 泛型用于生命周期参数?

问题描述

我正在尝试使async_trait某些实现对于具有生命周期参数的类型是通用的:

use async_trait::async_trait;

struct MyLifetimeType<'a> {
  s: &'a mut String,
}

#[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");
  }
}

当我尝试编译它时,我得到

error[E0276]: impl has stricter requirements than trait
  --> ...
   |
18 |   async fn handle(t: T);
   |   ---------------------- definition of `handle` from trait
...
25 |   async fn handle(t: MyLifetimeType<'a>) {
   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'async_trait`

似乎该问题与以某种方式使用引擎盖下async_trait的生命周期参数有关。'a当我摆脱所有asyncandasync_trait时,代码编译得很好。我怎样才能避免这个extra requirement错误?

对于更多上下文,解释为什么处理程序实现MyTrait可以对包含可变指针的结构进行操作:我有一个函数获取RwLockReadGuards 和RwLockWriteGuards 以获得几个不同的锁,然后将内容传递给处理程序。对于写保护,我需要一些方法让处理程序改变内容,所以我传递了一个可变指针。

标签: asynchronousrusttraitslifetime

解决方案


这是一个已知问题。作者建议在发生该错误时添加显式生命周期限制:

use async_trait::async_trait;

struct MyLifetimeType<'a> {
  s: &'a mut String,
}

#[async_trait]
trait MyTrait<T> {
  async fn handle(&self, t: T) where T: 'async_trait;
}

struct MyImpl;

#[async_trait]
impl<'a> MyTrait<MyLifetimeType<'a>> for MyImpl {

  async fn handle(&self, t: MyLifetimeType<'a>) {
    t.s.push_str("hi");
  }
  
}

推荐阅读