I'm learning Rust right now, and it seems I can't specify a closure as a function parameter. Here's what I have:
fn foo(a: i32, f: |i32| -> i32) -> i32 {
f(a)
}
fn main() {
let bar = foo(5, |x| { x + 1 });
println!("{}", bar);
}
I get the following error:
foo.rs:1:19: 1:20 error: expected type, found `|`
foo.rs:1 fn foo(a: i32, f: |i32| -> i32) -> i32 {
Okay, so it didn't like the closure syntax. This is sort of annoying, because now I have to write this:
fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 {
f(a)
}
fn main() {
let bar = foo(5, Box::new(|x| { x + 1 }));
println!("{}", bar);
}
So what's going on? I've read in a few different places that the first example is valid, so was this "closure type parameter" syntax removed, or am I just doing something wrong?
If we wanted to pass that closure into a function so it can be run inside that function, we would specify the parameter type as () -> Void . That means “accepts no parameters, and returns Void ” – Swift's way of saying “nothing”.
Swift Closure Declarationparameters - any value passed to closure. returnType - specifies the type of value returned by the closure. in (optional) - used to separate parameters/returnType from closure body.
Keyword fnFunctions are the primary way code is executed within Rust. Function blocks, usually just called functions, can be defined in a variety of different places and be assigned many different attributes and modifiers.
If anyone is interested in this question today, here's the syntax with generics:
fn foo<F: Fn(i32) -> i32>(a: i32, f: F) -> i32 {
f(a)
}
fn main() {
let bar = foo(5, |x| { x + 1 });
println!("{}", bar);
}
Or, using trait objects:
fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 {
f(a)
}
fn main() {
let bar = foo(5, Box::new(|x| { x + 1 }));
println!("{}", bar);
}
You should prefer the former.
Rust has been developed in the open from the beginning and the language has evolved a lot since then. The Stack Overflow article you're linking to is almost 1 year old, which in pre-1.0 Rust time is as long as a lifetime... (pun intended)
The most straightforward answer would be: keep in mind that a lot of articles, blogs posts, SO answers... are not relevant anymore because the language changed. If you try a solution and it doesn't work, just find the newer syntax (as you did!) and move on.
For this specific case, this RFC documents the change from |...| -> ...
to Fn/FnMut/FnOnce(...) -> ...
.
By the way, there is a plan for a community effort to find outdated articles and explicitly mark them as deprecated, in order for this particular problem to be avoided. I can't find the link to it, though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With