我有一个WriterJob
结构体。它的功能并不重要;它所做的是生成一个长时间运行的任务,并提供调用者一个API来检查作业的状态。
pub(crate) struct WriterJob {
...,
status: Status,
}
impl WriterJob {
async fn writer_job_impl(&mut self, rx: Receiver<WriteCommand>) {
// Job implementation details. It's important that `self` is mutuable
// since I update the job status
// eg.
// self.status = Status::Ready;
}
pub(crate) fn status(&self) -> Status {
self.status
}
pub(crate) fn spawn_writer_job(&mut self) -> Sender<WriteCommand> {
let (tx, rx) = mpsc::channel(10);
let handle = tokio::spawn(async move {
self.writer_job_impl(rx).await;
});
self.status = Status::Spawned;
tx
}
我遇到了这个错误:
error[E0521]: borrowed data escapes outside of associated function
--> src/io/buffered_write.rs:92:22
|
89 | pub(crate) fn spawn_writer_job(&mut self) -> Sender<WriteCommand> {
| ---------
| |
| `self` is a reference that is only valid in the associated function body
| let's call the lifetime of this reference `'1`
...
92 | let handle = tokio::spawn(async move {
| ______________________^
93 | | self.writer_job_impl(rx).await;
94 | | });
| | ^
| | |
| |__________`self` escapes the associated function body here
| argument requires that `'1` must outlive `'static`
我认为编译器抱怨它不知道 self
是否会像生成的任务一样长寿,因此出现了生命周期错误。但我不确定如何解决这个问题。一种可能的方法是使用 Arc<Mutex<Status>>
或 Arc<RwLock<Status>>
,但我不喜欢这种方法,因为我可能需要在 self
中添加更多可变字段。有更简洁的方法吗?
self
?它并不知道任务将运行多长时间,因此使其正常工作的唯一方法是通过 移动self
或使用内部可变性。 - Peter Hallstruct
上使用pub(crate)
可能有些多余。 - tadmanstatus
提取到一个单独的状态结构体中,并用Arc<Mutex>
包装它。你想要从不同的线程读写它,所以必须以某种方式进行同步。如果你不想使用互斥锁,可以切换到原子操作或原子枚举。 - xamgore