This troubled me for 2 years:
use std::thread;
struct Adder {
v: i32,
}
impl Adder {
fn add(&mut self, x: i32) {
let jh = thread::spawn(move || {
self.v += x;
});
jh.join().unwrap();
}
}
Quite easy and wrong, ahahaha.
borrowed data escapes outside of method
--> src\lib.rs:9:18
|
8 | fn add(&mut self, x: i32) {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
9 | let jh = thread::spawn(move || {
| __________________^
10 | | self.v += x;
11 | | });
| | ^
| | |
| |__________`self` escapes the method body here
| argument requires that `'1` must outlive `'static`
I know this is due to thread::spawn
's signature asking for a 'static
lifetime.
pub fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
And I do know it is not necessary to spawn
a job to do such an add.
But I really think it cannot lead a bug if compiler allows this, and I do want to make this complile without RefCell
, AtomicI32
, Mutex
and so on.
Facts:
- I cannot have multi
&mut self
add
spawns only one thread, and block until it finishing, as if only running on main thread- I only have one mut ref, I cannot spawn mutil
add
jobs
No possibility to lead a trace condition.
So, is there any trick to do so or whether I omit anything important?