Syntax for function as a function parameter


#1

I was searching for information about how to pass a function as a function parameter and I found the following Reddit post: https://www.reddit.com/r/rust/comments/2iuloj/is_there_such_things_as_pointers_to_functions_or/

The post included the following example along with a link to the code on the Rust Playground: http://is.gd/SCkan4

fn twice(x: int, f: |int| -> int) -> int {
    f(x) + f(x)
}

fn square(x: int) -> int { x * x }

fn main() {
    twice(5i, square); // evaluates to 50
}

But compiling the code gives an error:

<anon>:1:21: 1:22 error: expected type, found `|`
<anon>:1 fn twice(x: int, f: |int| -> int) -> int { f(x) + f(x) }
                             ^
playpen: application terminated with error code 101

I assume that the example worked in the past and that the syntax has changed since it was posted. I’d be curious to know what the correct syntax is now.


#2

Take a look at the Closure section in the rust book : https://doc.rust-lang.org/stable/book/closures.html

Specifically the section on “Taking closures as arguments”

https://play.rust-lang.org/?gist=a304be5844dda0acf87a&version=stable

fn twice<F>(x: i32, f: F) -> i32 
where F: Fn(i32) -> i32
{
    f(x) + f(x)
}

fn square(x: i32) -> i32 { x * x }

fn main() {
    println!("{}", twice(5, square));
}

#3

A variation on this is to take it as a trait object:

fn twice(x: i32, f: &Fn(i32) -> i32) -> i32 {
    f(x) + f(x)
}

fn square(x: i32) -> i32 { x * x }

fn main() {
    println!("{}", twice(5, &square));
}

If you’re absolutely sure you don’t want closures, there’s

fn twice(x: i32, f: fn(i32) -> i32) -> i32 {
    f(x) + f(x)
}

#4

Thanks.

A related question I had is what is the difference between Fn and fn? I see both are used in your post and I’ve seen both used in different contexts elsewhere, but I don’t know exactly what the difference between the two is.


#5

The Fn* traits are covered in the ‘Closures’ chapter linked above.

fn is just a function pointer, these are mostly useful for interacting with different languages (see the ‘FFI’ chapter).


#6

It’s also discussed here and in the surrounding sections. This drew heavily upon huonw’s excellent analysis though it doesn’t mention fn() at all.