我正在追求我的Rust之旅(非常喜欢),并且我正在探索线程。像往常一样,我遇到了一个我不理解的错误。
这是一个最简示例:
use std::thread;
pub fn compute_something(input: &Vec<&usize>) -> usize {
input.iter().map(|v| *v).sum()
}
pub fn main() {
let items = vec![0, 1, 2, 3, 4, 5];
let mut slice: Vec<&usize> = Vec::new();
slice.push(&items[1]); // borrowed value does not live long enough
// argument requires that `items` is borrowed for `'static`
slice.push(&items[2]); // borrowed value does not live long enough
// argument requires that `items` is borrowed for `'static`
assert_eq!(3, compute_something(&slice));
let h = thread::spawn(move || compute_something(&slice));
match h.join() {
Ok(result) => println!("Result: {:?}", result),
Err(e) => println!("Nope: {:?}", e)
}
} // `items` dropped here while still borrowed
当然我做了一个playground来说明。
如果我删除线程部分(即assert_eq!
行后面的所有内容),只调用compute_something(&slice)
,则可以编译通过。
以下是我不明白的三个主要问题:
为什么在程序末尾借用
items
时删除它会有问题?运行时不应该能够很好地清理内存吗?毕竟我无法在main
之外访问slice
。还有哪些部分会在程序结束时借用
items
?是slice
吗?如果是这样,为什么删除assert_eq!
行之后同样的程序就可以编译通过?我看不出它如何改变借用模式。为什么从线程的闭包中调用
compute_something
会创建问题,我该如何解决?