Reputation: 5827
Let thread state consists of immutable parameters Params
and the rest of the (mutable) state State
.
I am trying to mock spawning a thread that does something being controlled by parameters 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; /* ... */ })
}
}
But this does not work:
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 `[[email protected]:21:23: 21:42 params:&Params]` will meet its required lifetime bounds
--> test.rs:21:9
|
21 | thread::spawn(move || { params; /* ... */ })
| ^^^^^^^^^^^^^
I understand why it does not work: The thread could run indefinitely long, and the params
could be destroyed before it is terminated. That's clearly an error.
Now explain what is the proper way to make params
long at least as long as the thread. In other words, help to correct the above code. What should I do with lifetimes?
Upvotes: 0
Views: 74
Reputation: 30111
You got the right idea with using clone
and a move
lambda, but you forgot one detail: Params
isn't Clone
! Therefore the compiler did the best it could when it saw self.params.clone()
and cloned… the reference.
That's why the error messages have two &
here:
= note: expected `&&Params`
found `&&'a Params`
Your issue is solved by using #[derive(Clone)] struct Params { /* … */ }
.
Upvotes: 1