Sharing State in Rust Closures

The above code would be roughly rewritten as follows by the Rust compiler.struct ClosureType<'a> { c: &'a mut i32,}impl<'a> ClosureType<'a> { fn call(&mut self) { *self.c += 1; println!("in the closure, c={}",self.c); }}fn main() { let mut c = 0; let mut closure = ClosureType { c:&mut c }; closure.call(); println!("out of the closure, c={}", c);}The lifetimes make this example a little ugly so ignore them if you hate them and haven’t learned to love them, or haven’t even learned to hate them… The important thing to note here is that a closure is a struct!.Specifically, a struct with a field for each variable it captures, which in this example is ‘c’..You can see in the main function that c is borrowed mutably..Now the compiler error is much easier to understand..ClosureType borrows mutably so println can’t use it.Interestingly enough, a “move” on the closure would actually compile..A move causes the closure to take ownership of the variables it captures instead of just borrowing them..In a similar format to above, the closure struct no longer needs a litfetime because it now owns ‘c’.struct ClosureType { c: i32,}impl ClosureType { fn call(&mut self) { self.c += 1; println!("in the closure, c={}", self.c); }}fn main() { let mut c = 0; let mut closure = ClosureType { c:c }; closure.call(); println!("out of the closure, c={}", c);}But do you notice the problem here?.The program printsin the closure, c=1out of the closure, c=0That’s because c is copied into the closure while the original still exists and is unaffected by the closure operation..If you change ‘c’ to a type that does not implement the Copy trait, like a vector, then the borrow checker will throw an error on compilation..In that situation the type is not copyable so the closure takes ownership of the one an only variable ‘c’, and the second println is left referencing a moved value..See how that was easier to understand when viewing closures as their underlying structs?Now for a real solution to the problem of referencing a value after a closure has changed it..The fact is that in order to achieve this, we’ll need multiple references to the same value, one of which is mutable.. More details

Leave a Reply