Skip to content

Commit aa8602e

Browse files
committed
Guide: closures
1 parent d7cfc34 commit aa8602e

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
@@ -3642,7 +3642,209 @@ guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
36423642

36433643
# Patterns
36443644

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

36473849
# iterators
36483850

0 commit comments

Comments
 (0)