@@ -1647,14 +1647,14 @@ $ cargo build
1647
1647
$
1648
1648
```
1649
1649
1650
- Excellent! Open up your ` src/guessing_game .rs ` again. We'll be writing all of
1650
+ Excellent! Open up your ` src/main .rs ` again. We'll be writing all of
1651
1651
our code in this file. We'll talk about multiple-file projects later on in the
1652
1652
guide.
1653
1653
1654
1654
## Processing a Guess
1655
1655
1656
1656
Let's get to it! The first thing we need to do for our guessing game is
1657
- allow our player to input a guess. Put this in your ` src/guessing_game .rs ` :
1657
+ allow our player to input a guess. Put this in your ` src/main .rs ` :
1658
1658
1659
1659
``` {rust,no_run}
1660
1660
use std::io;
@@ -1734,9 +1734,9 @@ this using `cargo build`:
1734
1734
``` {notrust,no_run}
1735
1735
$ cargo build
1736
1736
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
1737
- src/guessing_game .rs:7:26: 7:34 error: the type of this value must be known in this context
1738
- src/guessing_game .rs:7 let secret_number = (rand::random() % 100i) + 1i;
1739
- ^~~~~~~~
1737
+ src/main .rs:7:26: 7:34 error: the type of this value must be known in this context
1738
+ src/main .rs:7 let secret_number = (rand::random() % 100i) + 1i;
1739
+ ^~~~~~~~
1740
1740
error: aborting due to previous error
1741
1741
```
1742
1742
@@ -1896,12 +1896,12 @@ If we try to compile, we'll get some errors:
1896
1896
``` {notrust,ignore}
1897
1897
$ cargo build
1898
1898
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
1899
- src/guessing_game .rs:20:15: 20:20 error: mismatched types: expected `int` but found `collections::string::String` (expected int but found struct collections::string::String)
1900
- src/guessing_game .rs:20 match cmp(input, secret_number) {
1901
- ^~~~~
1902
- src/guessing_game .rs:20:22: 20:35 error: mismatched types: expected `int` but found `uint` (expected int but found uint)
1903
- src/guessing_game .rs:20 match cmp(input, secret_number) {
1904
- ^~~~~~~~~~~~~
1899
+ src/main .rs:20:15: 20:20 error: mismatched types: expected `int` but found `collections::string::String` (expected int but found struct collections::string::String)
1900
+ src/main .rs:20 match cmp(input, secret_number) {
1901
+ ^~~~~
1902
+ src/main .rs:20:22: 20:35 error: mismatched types: expected `int` but found `uint` (expected int but found uint)
1903
+ src/main .rs:20 match cmp(input, secret_number) {
1904
+ ^~~~~~~~~~~~~
1905
1905
error: aborting due to 2 previous errors
1906
1906
```
1907
1907
@@ -1950,9 +1950,9 @@ And try compiling again:
1950
1950
``` {notrust,ignore}
1951
1951
$ cargo build
1952
1952
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
1953
- src/guessing_game .rs:20:15: 20:20 error: mismatched types: expected `uint` but found `collections::string::String` (expected uint but found struct collections::string::String)
1954
- src/guessing_game .rs:20 match cmp(input, secret_number) {
1955
- ^~~~~
1953
+ src/main .rs:20:15: 20:20 error: mismatched types: expected `uint` but found `collections::string::String` (expected uint but found struct collections::string::String)
1954
+ src/main .rs:20 match cmp(input, secret_number) {
1955
+ ^~~~~
1956
1956
error: aborting due to previous error
1957
1957
```
1958
1958
@@ -2053,9 +2053,9 @@ Let's try it out!
2053
2053
``` {notrust,ignore}
2054
2054
$ cargo build
2055
2055
Compiling guessing_game v0.1.0 (file:/home/you/projects/guessing_game)
2056
- src/guessing_game .rs:22:15: 22:24 error: mismatched types: expected `uint` but found `core::option::Option<uint>` (expected uint but found enum core::option::Option)
2057
- src/guessing_game .rs:22 match cmp(input_num, secret_number) {
2058
- ^~~~~~~~~
2056
+ src/main .rs:22:15: 22:24 error: mismatched types: expected `uint` but found `core::option::Option<uint>` (expected uint but found enum core::option::Option)
2057
+ src/main .rs:22 match cmp(input_num, secret_number) {
2058
+ ^~~~~~~~~
2059
2059
error: aborting due to previous error
2060
2060
```
2061
2061
@@ -3295,7 +3295,7 @@ fn times_four(x: int) -> int { x * 4 }
3295
3295
#[cfg(test)]
3296
3296
mod test {
3297
3297
use super::add_three;
3298
- use super::add_four ;
3298
+ use super::times_four ;
3299
3299
3300
3300
#[test]
3301
3301
fn test_add_three() {
@@ -3344,7 +3344,7 @@ about yet, and that's these lines:
3344
3344
3345
3345
``` {rust,ignore}
3346
3346
use super::add_three;
3347
- use super::add_four ;
3347
+ use super::times_four ;
3348
3348
```
3349
3349
3350
3350
Because we've made a nested module, we can import functions from the parent
@@ -3614,7 +3614,209 @@ guide](http://doc.rust-lang.org/guide-pointers.html#rc-and-arc).
3614
3614
3615
3615
# Patterns
3616
3616
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.
3618
3820
3619
3821
# iterators
3620
3822
0 commit comments