Skip to content

Commit 8888d7c

Browse files
committed
auto merge of #16206 : steveklabnik/rust/guide_lambdas, r=brson
2 parents 12e0f72 + aa8602e commit 8888d7c

File tree

1 file changed

+203
-1
lines changed

1 file changed

+203
-1
lines changed

src/doc/guide.md

+203-1
Original file line numberDiff line numberDiff line change
@@ -3614,7 +3614,209 @@ guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
36143614

36153615
# Patterns
36163616

3617-
# Lambdas
3617+
# Closures
3618+
3619+
So far, we've made lots of functions in Rust. But we've given them all names.
3620+
Rust also allows us to create anonymous functions too. Rust's anonymous
3621+
functions are called **closure**s. By themselves, closures aren't all that
3622+
interesting, but when you combine them with functions that take closures as
3623+
arguments, really powerful things are possible.
3624+
3625+
Let's make a closure:
3626+
3627+
```{rust}
3628+
let add_one = |x| { 1i + x };
3629+
3630+
println!("The 5 plus 1 is {}.", add_one(5i));
3631+
```
3632+
3633+
We create a closure using the `|...| { ... }` syntax, and then we create a
3634+
binding so we can use it later. Note that we call the function using the
3635+
binding name and two parentheses, just like we would for a named function.
3636+
3637+
Let's compare syntax. The two are pretty close:
3638+
3639+
```{rust}
3640+
let add_one = |x: int| -> int { 1i + x };
3641+
fn add_one (x: int) -> int { 1i + x }
3642+
```
3643+
3644+
As you may have noticed, closures infer their argument and return types, so you
3645+
don't need to declare one. This is different from named functions, which
3646+
default to returning unit (`()`).
3647+
3648+
There's one big difference between a closure and named functions, and it's in
3649+
the name: a function "closes over its environment." What's that mean? It means
3650+
this:
3651+
3652+
```{rust}
3653+
fn main() {
3654+
let x = 5i;
3655+
3656+
let printer = || { println!("x is: {}", x); };
3657+
3658+
printer(); // prints "x is: 5"
3659+
}
3660+
```
3661+
3662+
The `||` syntax means this is an anonymous closure that takes no arguments.
3663+
Without it, we'd just have a block of code in `{}`s.
3664+
3665+
In other words, a closure has access to variables in the scope that it's
3666+
defined. The closure borrows any variables that it uses. This will error:
3667+
3668+
```{rust,ignore}
3669+
fn main() {
3670+
let mut x = 5i;
3671+
3672+
let printer = || { println!("x is: {}", x); };
3673+
3674+
x = 6i; // error: cannot assign to `x` because it is borrowed
3675+
}
3676+
```
3677+
3678+
## Procs
3679+
3680+
Rust has a second type of closure, called a **proc**. Procs are created
3681+
with the `proc` keyword:
3682+
3683+
```{rust}
3684+
let x = 5i;
3685+
3686+
let p = proc() { x * x };
3687+
println!("{}", p()); // prints 25
3688+
```
3689+
3690+
Procs have a big difference from closures: they may only be called once. This
3691+
will error when we try to compile:
3692+
3693+
```{rust,ignore}
3694+
let x = 5i;
3695+
3696+
let p = proc() { x * x };
3697+
println!("{}", p());
3698+
println!("{}", p()); // error: use of moved value `p`
3699+
```
3700+
3701+
This restriction is important. Procs are allowed to consume values that they
3702+
capture, and thus have to be restricted to being called once for soundness
3703+
reasons: any value consumed would be invalid on a second call.
3704+
3705+
Procs are most useful with Rust's concurrency features, and so we'll just leave
3706+
it at this for now. We'll talk about them more in the "Tasks" section of the
3707+
guide.
3708+
3709+
## Accepting closures as arguments
3710+
3711+
Closures are most useful as an argument to another function. Here's an example:
3712+
3713+
```{rust}
3714+
fn twice(x: int, f: |int| -> int) -> int {
3715+
f(x) + f(x)
3716+
}
3717+
3718+
fn main() {
3719+
let square = |x: int| { x * x };
3720+
3721+
twice(5i, square); // evaluates to 50
3722+
}
3723+
```
3724+
3725+
Let's break example down, starting with `main`:
3726+
3727+
```{rust}
3728+
let square = |x: int| { x * x };
3729+
```
3730+
3731+
We've seen this before. We make a closure that takes an integer, and returns
3732+
its square.
3733+
3734+
```{rust,ignore}
3735+
twice(5i, square); // evaluates to 50
3736+
```
3737+
3738+
This line is more interesting. Here, we call our function, `twice`, and we pass
3739+
it two arguments: an integer, `5`, and our closure, `square`. This is just like
3740+
passing any other two variable bindings to a function, but if you've never
3741+
worked with closures before, it can seem a little complex. Just think: "I'm
3742+
passing two variables, one is an int, and one is a function."
3743+
3744+
Next, let's look at how `twice` is defined:
3745+
3746+
```{rust,ignore}
3747+
fn twice(x: int, f: |int| -> int) -> int {
3748+
```
3749+
3750+
`twice` takes two arguments, `x` and `f`. That's why we called it with two
3751+
arguments. `x` is an `int`, we've done that a ton of times. `f` is a function,
3752+
though, and that function takes an `int` and returns an `int`. Notice
3753+
how the `|int| -> int` syntax looks a lot like our definition of `square`
3754+
above, if we added the return type in:
3755+
3756+
```{rust}
3757+
let square = |x: int| -> int { x * x };
3758+
// |int| -> int
3759+
```
3760+
3761+
This function takes an `int` and returns an `int`.
3762+
3763+
This is the most complicated function signature we've seen yet! Give it a read
3764+
a few times until you can see how it works. It takes a teeny bit of practice, and
3765+
then it's easy.
3766+
3767+
Finally, `twice` returns an `int` as well.
3768+
3769+
Okay, let's look at the body of `twice`:
3770+
3771+
```{rust}
3772+
fn twice(x: int, f: |int| -> int) -> int {
3773+
f(x) + f(x)
3774+
}
3775+
```
3776+
3777+
Since our closure is named `f`, we can call it just like we called our closures
3778+
before. And we pass in our `x` argument to each one. Hence 'twice.'
3779+
3780+
If you do the math, `(5 * 5) + (5 * 5) == 50`, so that's the output we get.
3781+
3782+
Play around with this concept until you're comfortable with it. Rust's standard
3783+
library uses lots of closures, where appropriate, so you'll be using
3784+
this technique a lot.
3785+
3786+
If we didn't want to give `square` a name, we could also just define it inline.
3787+
This example is the same as the previous one:
3788+
3789+
```{rust}
3790+
fn twice(x: int, f: |int| -> int) -> int {
3791+
f(x) + f(x)
3792+
}
3793+
3794+
fn main() {
3795+
twice(5i, |x: int| { x * x }); // evaluates to 50
3796+
}
3797+
```
3798+
3799+
A named function's name can be used wherever you'd use a closure. Another
3800+
way of writing the previous example:
3801+
3802+
```{rust}
3803+
fn twice(x: int, f: |int| -> int) -> int {
3804+
f(x) + f(x)
3805+
}
3806+
3807+
fn square(x: int) -> int { x * x }
3808+
3809+
fn main() {
3810+
twice(5i, square); // evaluates to 50
3811+
}
3812+
```
3813+
3814+
Doing this is not particularly common, but every once in a while, it's useful.
3815+
3816+
That's all you need to get the hang of closures! Closures are a little bit
3817+
strange at first, but once you're used to using them, you'll miss them in any
3818+
language that doesn't have them. Passing functions to other functions is
3819+
incredibly powerful. Next, let's look at one of those things: iterators.
36183820

36193821
# iterators
36203822

0 commit comments

Comments
 (0)