我和时雄一起工作,我花了一整天的时间试图创建一个未来的向量。
我总是和借位检查员打起来,直到最后有人建议使用async move {}
技巧。
我不明白为什么这个方法有效(不像天真的方法)。
有人能帮我弄明白吗?
use futures::future;
async fn kill(processes: Vec<tokio::process::Child>) {
let mut deaths = Vec::new();
for mut p in processes {
// following works
deaths.push(async move { p.kill().await });
// naive approach would trigger error:
// deaths.push(p.kill());
// "borrowed value does not live long enough"
}
future::join_all(deaths).await;
}
1条答案
按热度按时间kwvwclae1#
每次编写
async { ... }
时,Rust编译器都会为状态机生成代码,我们称之为任务。在示例中,任务被收集到一个向量中,但实际上只有在循环完成后才执行。简单地说,Rust生成的任务看起来像这样:
如果没有
move
关键字,这些任务会保留p
的 references。p
只存在于循环的一次迭代中,但是任务在循环之后运行,所以这个引用是无效的-如果Rust允许您使用它,它将是一个悬空指针,触发Undefined Behavior。写入
move async
意味着生成的任务已经取得了p
的所有权。它不再是一个引用,值是任务的一部分: