一个关于迭代器和所有权的问题?
我是 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
回复
1个回答

test
2024-07-17
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
短。
=============
可以看另一个例子:
use std::sync::mpsc;
fn main() {
let (tx, _) = mpsc::channel();
let zz = String::from("xx");
tx.send(&zz);
}
Compiling playground v0.0.1 (/playground)
error[E0597]: `zz` does not live long enough
--> src/main.rs:6:11
|
6 | tx.send(&zz);
| ^^^ borrowed value does not live long enough
7 | }
| -
| |
| `zz` dropped here while still borrowed
| borrow might be used here, when `tx` is dropped and runs the `Drop` code for type `Sender`
|
= note: values in a scope are dropped in the opposite order they are defined
For more information about this error, try `rustc --explain E0597`.
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容