Rust: Executing dereferenced closure inside a task -
i have code takes vector of functions , iterates on them , executes each 1 @ each step. trying incorporate tasks loop these function calls can executed asynchronously instead of having first 1 block second 1 , on...
let mut arr: vec<|i32| -> i32> = vec::new(); arr.push(function1); arr.push(function2); let ref num_in = os::args()[1]; let num_str = num_in.to_string(); let num = match from_str::<i32>(num_str.as_slice()) { some(x) => x, none => panic!("not number"), }; f in arr.iter_mut() { spawn(proc(){ println!("{}", (*f)(num.clone())); }); };
without task, , doing println!
inside loop code runs fine, in blocking way trying avoid using tasks. task these errors , notes...
error: trait 'core::kinds::send' not implemented type '&mut |i32| -> i32'
note: closure captures 'f' requires captured variables implement trait 'core::kinds::send'
there couple of issues in code:
f
is, compiler telling you, &mut |i32|->i32
. it's borrowed reference 1 of vector elements. such borrowed reference cannot sent across task boundary. easy rule prevent dangling pointers , memory safety errors because scope-based lifetime guarantees don't work if multiple threads involved.
but of type |i32|->i32
borrowed reference (generally) because borrows environment. if don't capture variables (“empty environment”), use fn(i32) -> i32
instead sendable. can think of simple function pointer.
letting other tasks execute carries own environment (as in “not borrowed”) done proc
. that's purpose. you're using proc
s reason. compiler copies f
proc
makes whole proc
non-sendable because borrowed reference non-sendable.
in near future, we'll “unboxed closures” make proc
s superfluous. then, should able use vec<box<fnonce(i32)->i32 + send>>
or vec<box<fn(i32)->i32 + send>>
replacement vec<proc(i32)->i32>
. , creating these kinds of boxes involve box
, move
keyword cast trait object.
Comments
Post a Comment