I just started Rust programming this week and I am trying to build a project to learn it. I encountered this problem today and I couldn't understand why it occurred. I did search around the forum and the internet but all other questions do not seem to be applicable to mine.
The original code is very long so I abstracted it into a simplified version:
use std::{thread, time};
use std::f32;
use std::io::stdin;
struct Car {
x: f32,
y: f32,
}
impl Car {
fn cur_pos(&self) -> (f32, f32) {
(12.331, 14.112) // suppose some device returns coordinates
}
fn take_order(&self, order: &str) {
println!("You want me to drive: {}", order);
}
fn new() -> Car {
Car {
x: 0.0,
y: 0.0,
}
}
}
fn main() {
let car = Car::new();
thread::spawn(|| {
loop {
let (x, y) = car.cur_pos();
println!("Current position is {}, {}", x, y);
thread::sleep(time::Duration::from_millis(2000));
}
});
let mut s = String::new();
loop {
stdin().read_line(&mut s).expect("Did not enter a correct string");
car.take_order(&s);
}
}
When compiling, I got:
error[E0373]: closure may outlive the current function, but it borrows `car`, which is owned by the current function
--> src/simple.rs:29:19
|
29 | thread::spawn(|| {
| ^^ may outlive borrowed value `car`
30 | loop {
31 | let (x, y) = car.cur_pos();
| --- `car` is borrowed here
help: to force the closure to take ownership of `car` (and any other referenced variables), use the `move` keyword
|
29 | thread::spawn(move || {
| ^^^^^^^
My understanding of this problem is, rustc
thinks that the variable car
will die after main()
quits and the closure may still be alive and therefore the closure will reference garbage. However, this doesn't make sense since as the thread dies when main()
quits. So I think both the closure and main()
should have the same life time, which is static
.
Failed Approaches
I have tried to solve it by letting the closure take the ownership but the loop after it needs it so I can't really do it.
I have also tried to warp car
into Arc
so we have a multi-ownership thread safe car
. However, the same error persists.
Thanks.