4 ms·
Actually you're right, I didn't realize that the compiler treated a single &mut references like that. I wonder if what I'm thinking of involved &mut self captu
by vvanders 9y ago
Actually you're right, I didn't realize that the compiler treated a single &mut references like that.
I wonder if what I'm thinking of involved &mut self captures that were happening as part of an impl on a struct. There's definitely some cases there where I was getting tripped up on it.
- vvanders 9y agoAh, 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); });