Я создаю сервис в Rust, используя tokio-rs, и до сих пор был доволен этим техническим стеком. Сейчас я пытаюсь объединить асинхронные операции, которые включают в себя запись и затрудняются с проверкой заимствований.
Мой упрощенный пример минимального кода такой:
extern crate futures; // 0.1.21
use futures::Future;
use std::{cell::RefCell, rc::Rc};
trait RequestProcessor {
fn prepare(&self) -> Box<Future<Item = (), Error = ()>>;
fn process(&mut self, request: String) -> Box<Future<Item = (), Error = ()>>;
}
struct Service {
processor: Rc<RefCell<RequestProcessor>>,
}
impl Service {
fn serve(&mut self, request: String) -> Box<Future<Item = (), Error = ()>> {
let processor_clone = self.processor.clone();
let result_fut = self
.processor
.borrow()
.prepare()
.and_then(move |_| processor_clone.borrow_mut().process(request));
Box::new(result_fut)
}
}
fn main() {}
Как краткое резюме, после шага подготовки к асинхронности я пытаюсь запустить другую асинхронную операцию, которая записывает поле self
. Без изменчивости это легко работает с простым членом Rc
, но изменчивость нарушает его, вызывая следующую ошибку:
error[E0597]: `processor_clone` does not live long enough
--> src/main.rs:22:32
|
22 | .and_then(move |_| processor_clone.borrow_mut().process(request));
| ^^^^^^^^^^^^^^^ - `processor_clone` dropped here while still borrowed
| |
| borrowed value does not live long enough
|
= note: values in a scope are dropped in the opposite order they are created
Я ожидаю, что это должно сработать, я не вижу, где по-прежнему заимствована изменяемая ссылка. Я думаю, что process()
должен освободить процессор &mut self
после того, как будет возвращено будущее, поэтому ошибка компиляции не должна возникать.
Не могли бы вы объяснить основные причины? Как изменить этот пример, чтобы он был принят компилятором?