I'm trying to use a for loop to iterate over a vector of functions and execute each function at each step.
fn f1(i: i32) -> i32 {
i * 2
}
fn f2(i: i32) -> i32 {
i * 4
}
fn main() {
let mut arr: Vec<|i32| -> i32> = Vec::new();
arr.push(f1);
arr.push(f2);
for f in arr.iter() {
println!("{}", f(1));
}
}
But the attempted execution of f(1)
gives this error:
error: expected function, found '&|i32| -> i32'
I guess in putting the functions in the vector their type is mutated and no longer works like a normal function. Is there a way to transform it back, or am I missing something?
As of Rust 1.x, unboxed closures are the only kind of closures in the language, and they don't need a feature flag. Moreover, static functions can easily be converted to unboxed closures. Therefore, the correct way to call functions from a vector of functions is:
I've used
Fn()
closures which can access their environment through a shared reference, so it is sufficient to iterate the vector by reference. If I had used aFnMut()
closure, I would have had to use iteration by mutable reference:A similar idea holds for
FnOnce()
and iteration by value, although here we need to useBox
to own the closure:Alternatively, if you know that you only work with static functions, it is possible to store pointers to them directly, without using closure traits:
While
f1
andf2
actually have different incompatible types, they are automatically coerced to the general function pointer typefn(i32) -> i32
when used in appropriate context, like in the example above.Because static functions don't have any environment, you can freely clone references to them and call them through any kind of reference. This is probably the way to go if you only need static functions.
This answer was updated for Rust 1.x; older versions of the answer remain in the edit history.