Gave VisualRust another try and to see how far they got, I wrote a few lines of code. And as usual, the code causes me to write a question on stackoverflow...
See first, read my question later:
fn make_counter( state : &mut u32 ) -> Box<Fn()->u32>
{
Box::new(move || {let ret = *state; *state = *state + 1; ret })
}
fn test_make_counter() {
let mut cnt : u32 = 0;
{
let counter = make_counter( & mut cnt );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
}
fn alt_make_counter ( init : u32 ) -> Box<Fn()->u32> {
let mut state = init;
Box::new(move || {let ret = state; state = state + 1; ret })
}
fn test_alt_make_counter() {
let counter = alt_make_counter( 0u32 );
let x1 = counter();
let x2 = counter();
println!("x1 = {} x2 = {}",x1,x2);
}
fn main() {
test_make_counter();
test_alt_make_counter();
}
The difference between make_counter()
and alt_make_counter()
is, that in one case, the state is a pointer to a mutable u32 passed to the function and in the other case, it is a mutable u32 defined inside the function. As the test_make_counter() function shows clearly, there is no way, that the closure lives longer than the variable cnt
. Even if I removed the block inside test_make_counter()
they would still have the identical lifetime. With the block, the counter
will die before cnt
. And yet, Rust complains:
src\main.rs(4,2): error : captured variable
state
does not outlive the enclosing closure src\main.rs(3,1): warning : note: captured variable is valid for the anonymous lifetime #1 defined on the block at 3:0
If you look at the alt_make_counter()
function now, the lifetime of state
should basically cause the same error message, right? If the code captures the state for the closure, it should not matter if the pointer is passed in or if the variable is bound inside the function, right? But obviously, those 2 cases are magically different.
Who can explain, why they are different (bug, feature, deep insight, ...?) and if there is a simple rule one can adopt which prevents wasting time over such issues now and then?