我是 Rust 的新手,跟着 Rust 权威指南和视频学到了并发章节,有个例子遇到了点问题:
use std::{sync::mpsc, thread, time::Duration};
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
let v = vec![
String::from("Hello"),
String::from("I'm XiaoMing"),
String::from("I come from China"),
String::from("Nice to meet you"),
];
for s in v.iter() {
tx.send(s).unwrap();
thread::sleep(Duration::from_millis(300));
}
});
for msg in rx {
println!("{}", msg);
}
}
我的 VSCode 在 v.iter()
处报了错:
`v` does not live long enough
borrowed value does not live long enoughrustcE0597
main.rs(18, 3): `v` dropped here while still borrowed
main.rs(4, 8): lifetime `'1` appears in the type of `tx`
main.rs(15, 7): argument requires that `v` is borrowed for `'1`
我知道 for in
循环会取得迭代器的所有权,iter
方法的第一个参数是 &self
,它没有取得 v
的所有权,迭代器的所有权转移了,为什么 v
会失效?
另外如果我不调用 iter
直接用 v
去循环就能通过,这两种有什么区别吗?
====== 补充下在 rust playground 里的错误信息,可能有帮助:
Compiling playground v0.0.1 (/playground)
error[E0597]: `v` does not live long enough
--> src/main.rs:14:14
|
4 | let (tx, rx) = mpsc::channel();
| -- lifetime `'1` appears in the type of `tx`
...
14 | for s in v.iter() {
| ^^^^^^^^ borrowed value does not live long enough
15 | tx.send(s).unwrap();
| ---------- argument requires that `v` is borrowed for `'1`
...
18 | });
| - `v` dropped here while still borrowed
For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` due to previous error
for s in v
,s 拿到了 v 中元素的所有权。元素就不再被 v 拥有了。这样元素的 life 也就与 v 无关了。此时 send 的参数不是引用,没有 life 的问题。for s in v.iter()
,这是一个只读迭代,s 没有拿到 v 中元素的所有权,只是一个引用。tx.send
拿到一个这个引用,他需要引用的 life 比tx
更长(或者一样长)。但是这里,s 是比 tx 后声明的,所以 lifetime 会先先比 tx 先终止,life 比s
对v
中元素引用的 life 是与v
一样长的,在作为spawn
的参数的函数外,v
的 life 就结束了,但是tx
还在,这是不行的。tx
短。=============
可以看另一个例子: