编译此程序时遇到问题:
use std::env; use std::sync::mpsc; use std::thread; use std::time::Duration; fn main() { let args: Vec<_> = env::args().skip(1).collect(); let (tx, rx) = mpsc::channel(); for arg in &args { let t = tx.clone(); thread::spawn(move || { thread::sleep(Duration::from_millis(50)); let _new_arg = arg.to_string() + "foo"; t.send(arg); }); } for _ in &args { println!("{}", rx.recv().unwrap()); } }
我从命令行读取所有参数,并模拟对线程中的每个参数做一些工作.然后我打印出这项工作的结果,我使用一个频道.
error[E0597]: `args` does not live long enough
--> src/main.rs:11:17
|
11 | for arg in &args {
| ^^^^ does not live long enough
...
24 | }
| - borrowed value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
如果我理解得很好..生命周期args
必须是static
(即程序执行的整个时间),而它只存在于main
函数范围内(?).我不明白这背后的原因,以及我如何解决它.
问题在于产生后台线程.当你thread::spawn
有效地调用你时,必须将其中使用的任何资源的所有权传递给线程,因为它可能无限期地运行,这意味着它的生命周期必须是'static
.
有两种方法可以解决这个问题:最简单的方法是通过所有权.你的代码在这里
let new_arg = arg.to_string() + "foo"; t.send(arg);
看起来你真的想要发送new_arg
,在这种情况下你可以arg.to_string()
在产生线程之前创建自己的结果,从而消除传递引用的需要arg
.
另一个稍微涉及的想法,虽然在某些方面可能有用,但是例如在横梁中实现的范围线程.这些绑定到一个显式范围,您可以在其中生成它们并在最后连接在一起.这看起来有点像这样:
crossbeam::scope(|scope| { scope.spawn(|| { println!("Hello from a scoped thread!"); }); });
有关详细信息,请查看文档.