Skip to content

Commit ac9f659

Browse files
committed
---
yaml --- r: 115426 b: refs/heads/try c: f7d2d58 h: refs/heads/master v: v3
1 parent e471d2c commit ac9f659

File tree

2 files changed

+47
-34
lines changed

2 files changed

+47
-34
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: bee4e6adac17f87b1cdc26ab69f8c0f5d82575a3
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: ec0258a381b88b5574e3f8ce72ae553ac3a574b7
5-
refs/heads/try: 36f98fb0bb9875bb7901c5e0cc757fde6ac0acdb
5+
refs/heads/try: f7d2d5876c4d26dd5941c723aad2fc53c6fcc9aa
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/doc/tutorial.md

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,59 +1723,72 @@ let x = 3;
17231723
fn fun() -> () { println!("{}", x); }
17241724
~~~~
17251725
1726-
Rust also supports _closures_, functions that can access variables in
1727-
the enclosing scope. Compare `x` in these:
1726+
A _closure_ does support accessing the enclosing scope; below we will create
1727+
2 _closures_ (nameless functions). Compare how `||` replaces `()` and how
1728+
they try to access `x`:
17281729
1729-
~~~~
1730+
~~~~ {.ignore}
17301731
let x = 3;
17311732
17321733
// `fun` is an invalid definition
1733-
fn fun () -> () { println!("{}", x) }; // cannot reach enclosing scope
1734-
let closure = || -> () { println!("{}", x) }; // can reach enclosing scope
1734+
fn fun () -> () { println!("{}", x) }; // cannot capture enclosing scope
1735+
let closure = || -> () { println!("{}", x) }; // can capture enclosing scope
17351736
1736-
fun(); // Still won't work
1737-
closure(); // Prints: 3
1738-
~~~~
1737+
// `fun_arg` is an invalid definition
1738+
fn fun_arg (arg: int) -> () { println!("{}", arg + x) }; // cannot capture enclosing scope
1739+
let closure_arg = |arg: int| -> () { println!("{}", arg + x) }; // Can capture enclosing scope
1740+
// ^
1741+
// Requires a type because the implementation needs to know which `+` to use.
1742+
// In the future, the implementation may not need the help.
17391743
1740-
Closures can be utilized in this fashion:
1744+
fun(); // Still won't work
1745+
closure(); // Prints: 3
17411746
1747+
fun_arg(7); // Still won't work
1748+
closure_arg(7); // Prints: 10
17421749
~~~~
1743-
// Create a nameless function and assign it to `closure`. It's sole
1744-
// argument is a yet unknown `x` to be supplied by the caller.
1745-
let closure = |x| -> () { println!("{}", x) };
17461750
1747-
// Define `call_closure_with_ten` to take one argument and return null `()`.
1748-
// `fun` is a function which takes one `int` argument `|int|` and also returns
1749-
// null `()`. `|int|` defines the `fun` to be of type _closure_
1750-
fn call_closure_with_ten(fun: |int| -> ()) -> () { fun(10); }
1751+
Closures begin with the argument list between vertical bars and are followed by
1752+
a single expression. Remember that a block, `{ <expr1>; <expr2>; ... }`, is
1753+
considered a single expression: it evaluates to the result of the last
1754+
expression it contains if that expression is not followed by a semicolon,
1755+
otherwise the block evaluates to `()`.
17511756
1752-
// The caller supplies `10` to the closure
1753-
// which prints out the value
1754-
call_closure_with_ten(closure);
1755-
~~~~
1757+
Since a closure is an expression, the compiler can usually infer the argument and
1758+
return types; so they are often omitted. This is in contrast to a function which
1759+
is a declaration and _not_ an expression. Declarations require the types to be
1760+
specified and carry no inference. Compare:
17561761
1757-
This can be simplified by removing null arguments:
1762+
~~~~ {.ignore}
1763+
// `fun` cannot infer the type of `x` so it must be provided because it is a function.
1764+
fn fun (x: int) -> () { println!("{}", x) };
1765+
let closure = |x | -> () { println!("{}", x) };
17581766
1767+
fun(10); // Prints 10
1768+
closure(20); // Prints 20
1769+
1770+
fun("String"); // Error: wrong type
1771+
// Error: This type is different from when `x` was originally evaluated
1772+
closure("String");
17591773
~~~~
1760-
let closure = |x| println!("{}", x);
1761-
fn call_closure_with_ten(fun: |int|) { fun(10); }
17621774
1763-
call_closure_with_ten(closure);
1775+
The null arguments `()` are typically dropped so the end result
1776+
is more compact.
1777+
17641778
~~~~
1779+
let closure = |x| { println!("{}", x) };
17651780
1766-
Closures begin with the argument list between vertical bars and are followed by
1767-
a single expression. Remember that a block, `{ <expr1>; <expr2>; ... }`, is
1768-
considered a single expression: it evaluates to the result of the last
1769-
expression it contains if that expression is not followed by a semicolon,
1770-
otherwise the block evaluates to `()`.
1781+
closure(20); // Prints 20
1782+
~~~~
17711783
1772-
The types of the arguments are generally omitted, as is the return type,
1773-
because the compiler can almost always infer them. In the rare case where the
1774-
compiler needs assistance, though, the arguments and return types may be
1775-
annotated.
1784+
Here, in the rare case where the compiler needs assistance,
1785+
the arguments and return types may be annotated.
17761786
17771787
~~~~
17781788
let square = |x: int| -> uint { (x * x) as uint };
1789+
1790+
println!("{}", square(20)); // 400
1791+
println!("{}", square(-20)); // 400
17791792
~~~~
17801793
17811794
There are several forms of closure, each with its own role. The most

0 commit comments

Comments
 (0)