我用 Rust 编码已经有一段时间了,但我经常对这些细微差别感到措手不及。 例如,这有效:
use std::thread::JoinHandle;
fn main() {
let all_threads: Vec<JoinHandle<()>> = vec![];
for t in all_threads {
t.join().unwrap();
}
}
这不会(错误:无法移出共享引用后面的
*t
)
fn main() {
let all_threads: Vec<JoinHandle<()>> = vec![];
all_threads.iter_mut().for_each(move |t| t.join().unwrap());
}
我的印象是上面的代码片段是下面代码片段的语法糖,但显然我遗漏了一些东西。有人可以帮助我 for 循环如何将实例移出吗?
for
循环实际上是使用 IntoIterator
特性的语法糖,而不是示例中使用的 IterMut
。您可以在Rust 文档中查看有关如何脱糖的具体细节。
知道了这一点,我们可以更改您问题中的示例,以便现在可以编译:
use std::thread::JoinHandle;
fn main() {
let all_threads: Vec<JoinHandle<()>> = vec![];
all_threads.into_iter().for_each(move |t| t.join().unwrap());
}
IterMut::Iterator
实现产生&mut T
(对T
的可变引用),而IntoIterator::IntoIter
产生T
对象(拥有的对象)。由于 JoinHandle::join()
需要 self
(即它消耗该对象),因此它不适用于 IterMut
返回的可变引用。