#asynchronous #rust #traits #lifetime
Вопрос:
Я пытаюсь сделать async_trait
так, чтобы некоторые реализации были универсальными для типов с параметрами времени жизни:
use async_trait::async_trait;
struct MyLifetimeType<'a> {
s: amp;'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
под капотом. Когда я избавляюсь от всех async
и async_trait
, код компилируется нормально. Как я могу избежать этой extra requirement
ошибки?
Для более подробного контекста, чтобы объяснить, почему реализуются обработчики MyTrait
, которые могут работать со структурами, содержащими изменяемые указатели: у меня есть функция, которая получает RwLockReadGuard
s и RwLockWriteGuard
s для нескольких разных блокировок, а затем передает содержимое обработчику. Для защиты от записи мне нужен какой-то способ, чтобы обработчик изменял содержимое, поэтому я передаю изменяемый указатель.
Ответ №1:
Это известная проблема. Автор рекомендует добавлять явную привязку к сроку службы при возникновении этой ошибки:
use async_trait::async_trait;
struct MyLifetimeType<'a> {
s: amp;'a mut String,
}
#[async_trait]
trait MyTrait<T> {
async fn handle(amp;self, t: T) where T: 'async_trait;
}
struct MyImpl;
#[async_trait]
impl<'a> MyTrait<MyLifetimeType<'a>> for MyImpl {
async fn handle(amp;self, t: MyLifetimeType<'a>) {
t.s.push_str("hi");
}
}