让线程状态由不可变的参数Params
和(可变的(状态的其余部分State
组成。
我试图模拟生成一个线程,该线程执行由参数Params
:控制的操作
use std::thread;
struct Params {
x: i32,
}
struct State<'a> {
params: &'a Params,
y: i32,
}
impl<'a> State<'a> {
fn new(params: &Params) -> State {
State {
params,
y: 0,
}
}
fn start(&mut self) -> thread::JoinHandle<()> {
let params = self.params.clone();
thread::spawn(move || { params; /* ... */ })
}
}
但这不起作用:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> test.rs:20:34
|
20 | let params = self.params.clone();
| ^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 12:6...
--> test.rs:12:6
|
12 | impl<'a> State<'a> {
| ^^
note: ...so that the types are compatible
--> test.rs:20:34
|
20 | let params = self.params.clone();
| ^^^^^
= note: expected `&&Params`
found `&&'a Params`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@test.rs:21:23: 21:42 params:&Params]` will meet its required lifetime bounds
--> test.rs:21:9
|
21 | thread::spawn(move || { params; /* ... */ })
| ^^^^^^^^^^^^^
我理解为什么它不起作用:线程可能会无限长地运行,params
可能会在终止之前被销毁。这显然是个错误。
现在解释一下什么是使params
至少与线程一样长的正确方法。换句话说,帮助更正上述代码。我的一生该怎么办?
使用clone
和move
lambda的想法是正确的,但您忘记了一个细节:Params
不是Clone
!因此,编译器在看到self.params.clone()
并克隆…引用时尽了最大努力。
这就是为什么错误消息在这里有两个&
:
= note: expected `&&Params`
found `&&'a Params`
使用#[derive(Clone)] struct Params { /* … */ }
可以解决您的问题。