我正在使用 tokio-rs 在 Rust 中构建一个服务,并且到目前为止对这个技术堆栈很满意。我现在正在尝试链接包括写入在内的异步操作,并且很难使用借用检查器。
我简化的最小代码示例是这样的:
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
,所以不应该发生编译错误。
你能解释一下根本原因吗?这个例子应该如何改变才能被编译器接受?