2 ms·
Ah, now I remember why I tend to use this model: use std::thread; fn no_mut(a: &mut usize) { *a = 10; { let b: &usize = a; println
by vvanders 9y ago
Ah, now I remember why I tend to use this model:
use std::thread;
fn no_mut(a: &mut usize) {
*a = 10;
{
let b: &usize = a;
println!("a: {}, b: {}", a, b);
}
let b: &usize = a;
thread::spawn(|| {
println!("b: {}", b);
});
}
fn main() {
let mut foo = 42usize;
no_mut(&mut foo);
}
Similar code but the move throws an error(as it should).
If you don't have the value type then you're constrained by the parent mut lifetime here so it's not just as simple as a conversion that you can then pass around. Otherwise you need to consider all the lifetime scopes which can get a bit unwieldy.
- deleted 9y ago[deleted]
- danieldk 9y agoIf you don't have the value type then you're constrained by the parent mut lifetime here so it's not just as simple as a conversion that you can then pass around. You cannot move any closure to spawn that captures a non-static reference, since there is no guarantee that the value will live during the lifetime of the thread. (The closure is required to be Send + 'static.) E.g., you can't do (moving to a non-Copy type :)): let foo = String::new(); let t = thread::spawn(|| { println!("foo: {}", &foo); }); You could move the captures, including foo, but then foo cannot be used in its original scope anymore: let foo = String::new(); let t = thread::spawn(move || { println!("foo: {}", &foo); }); // This will give an error, because foo is moved. println!("{}", foo); Note that only moving values works, this does not compile (for the same reasons as the first example): let foo = String::new(); let bar = &foo; let t = thread::spawn(move || { println!("bar: {}", &bar); });