From e4c229b9fdb283c733fa8b157aa6d2eeab8eb5f3 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Wed, 5 Aug 2015 13:44:54 -0400 Subject: [PATCH] Add more infor about function pointers to TRPL 1. mention them in the function chapter 2. mention their coercion to closures in the closures chapter Fixes #26746 --- src/doc/trpl/closures.md | 29 +++++++++++++++++++++++++++++ src/doc/trpl/functions.md | 31 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md index ce52ea5d690cc..161c4ce90b240 100644 --- a/src/doc/trpl/closures.md +++ b/src/doc/trpl/closures.md @@ -316,6 +316,35 @@ assert_eq!(3, answer); Now we take a trait object, a `&Fn`. And we have to make a reference to our closure when we pass it to `call_with_one`, so we use `&||`. +# Function pointers and closures + +A function pointer is kind of like a closure that has no environment. As such, +you can pass a function pointer to any function expecting a closure argument, +and it will work: + +```rust +fn call_with_one(some_closure: &Fn(i32) -> i32) -> i32 { + some_closure(1) +} + +fn add_one(i: i32) -> i32 { + i + 1 +} + +let f = add_one; + +let answer = call_with_one(&f); + +assert_eq!(2, answer); +``` + +In this example, we don’t strictly need the intermediate variable `f`, +the name of the function works just fine too: + +```ignore +let answer = call_with_one(&add_one); +``` + # Returning closures It’s very common for functional-style code to return closures in various diff --git a/src/doc/trpl/functions.md b/src/doc/trpl/functions.md index ea927707ecd6f..5b29965efc60b 100644 --- a/src/doc/trpl/functions.md +++ b/src/doc/trpl/functions.md @@ -227,3 +227,34 @@ as any type: let x: i32 = diverges(); let x: String = diverges(); ``` + +## Function pointers + +We can also create variable bindings which point to functions: + +```rust +let f: fn(i32) -> i32; +``` + +`f` is a variable binding which points to a function that takes an `i32` as +an argument and returns an `i32`. For example: + +```rust +fn plus_one(i: i32) -> i32 { + i + 1 +} + +// without type inference +let f: fn(i32) -> i32 = plus_one; + +// with type inference +let f = plus_one; +``` + +We can then use `f` to call the function: + +```rust +# fn plus_one(i: i32) -> i32 { i + 1 } +# let f = plus_one; +let six = f(5); +```