@@ -495,16 +495,10 @@ let s = "a\
495
495
496
496
## Operators
497
497
498
- Rust's set of operators contains very few surprises. The main
499
- difference with C is that `++` and `--` are missing, and that the
500
- logical bitwise operators have higher precedence—in C, `x & 2 > 0`
501
- comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is
502
- more likely to be what you expect (unless you are a C veteran).
503
-
504
- Thus, binary arithmetic is done with `*`, `/`, `%`, `+`, and `-`
505
- (multiply, divide, remainder, plus, minus). `-` is also a unary prefix
506
- operator (there are no unary postfix operators in Rust) that does
507
- negation.
498
+ Rust's set of operators contains very few surprises. Binary arithmetic
499
+ is done with `*`, `/`, `%`, `+`, and `-` (multiply, divide, remainder,
500
+ plus, minus). `-` is also a unary prefix operator (there are no unary
501
+ postfix operators in Rust) that does negation.
508
502
509
503
Binary shifting is done with `>>` (shift right), and `<<` (shift
510
504
left). Shift right is arithmetic if the value is signed and logical if
@@ -528,6 +522,11 @@ let y: uint = x as uint;
528
522
assert y == 4u;
529
523
~~~~
530
524
525
+ The main difference with C is that `++` and `--` are missing, and that
526
+ the logical bitwise operators have higher precedence — in C, `x & 2 > 0`
527
+ comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is
528
+ more likely to be what you expect (unless you are a C veteran).
529
+
531
530
## Attributes
532
531
533
532
Every definition can be annotated with attributes. Attributes are meta
@@ -850,33 +849,32 @@ fn bar() -> int {
850
849
}
851
850
~~~~
852
851
853
- Rust also supports _closures_, functions that can
854
- access variables in the enclosing scope.
852
+ Rust also supports _closures_, functions that can access variables in
853
+ the enclosing scope.
855
854
856
855
~~~~
856
+ # import println = io::println;
857
857
fn call_closure_with_ten(b: fn(int)) { b(10); }
858
858
859
- let x = 20;
860
- let closure = |arg| #info("x =%d, arg=%d", x , arg);
859
+ let captured_var = 20;
860
+ let closure = |arg| println(#fmt("captured_var =%d, arg=%d", captured_var , arg) );
861
861
862
862
call_closure_with_ten(closure);
863
863
~~~~
864
864
865
- A closure is defined by listing the arguments, between bars, followed
866
- by an expression that acts as the function body. The types of the
867
- arguments are generally omitted, as is the return type, because
868
- the compiler can almost always infer them. In the rare case where
869
- the compiler needs assistance though, the arguments and return
870
- types may be annotated.
865
+ The types of the arguments are generally omitted, as is the return
866
+ type, because the compiler can almost always infer them. In the rare
867
+ case where the compiler needs assistance though, the arguments and
868
+ return types may be annotated.
871
869
872
870
~~~~
873
871
# type mygoodness = fn(str) -> str; type what_the = int;
874
872
let bloop = |well, oh: mygoodness| -> what_the { fail oh(well) };
875
873
~~~~
876
874
877
875
There are several forms of closure, each with its own role. The most
878
- common, called a _stack closure_ and written `&fn()` has direct access
879
- to local variables in the enclosing scope.
876
+ common, called a _stack closure_, has type `fn&` and can directly
877
+ access local variables in the enclosing scope.
880
878
881
879
~~~~
882
880
let mut max = 0;
@@ -888,10 +886,9 @@ allocated on the call stack and refers by pointer to captured
888
886
locals. To ensure that stack closures never outlive the local
889
887
variables to which they refer, they can only be used in argument
890
888
position and cannot be stored in structures nor returned from
891
- functions. Despite the usage limitations stack closures are used
889
+ functions. Despite the usage limitations stack closures are used
892
890
pervasively in Rust code.
893
891
894
-
895
892
### Boxed closures
896
893
897
894
When you need to store a closure in a data structure, a stack closure
@@ -922,6 +919,19 @@ fn main() {
922
919
}
923
920
~~~~
924
921
922
+ This example uses the long closure syntax, `fn@(s: str) ...`,
923
+ making the fact that we are declaring a box closure explicit. In
924
+ practice boxed closures are usually defined with the short closure
925
+ syntax introduced earlier, in which case the compiler will infer
926
+ the type of closure. Thus our boxed closure example could also
927
+ be written:
928
+
929
+ ~~~~
930
+ fn mk_appender(suffix: str) -> fn@(str) -> str {
931
+ ret |s| s + suffix;
932
+ }
933
+ ~~~~
934
+
925
935
### Closure compatibility
926
936
927
937
A nice property of Rust closures is that you can pass any kind of
@@ -946,18 +956,11 @@ Unique closures, written `fn~` in analogy to the `~` pointer type (see
946
956
next section), hold on to things that can safely be sent between
947
957
processes. They copy the values they close over, much like boxed
948
958
closures, but they also 'own' them—meaning no other code can access
949
- them. Unique closures mostly exist for spawning new [tasks](#tasks).
959
+ them. Unique closures are used in concurrent code, particularly
960
+ for spawning [tasks](#tasks).
950
961
951
962
### Do syntax
952
963
953
- The compact syntax used for stack closures (`|arg1, arg2| body`) can
954
- also be used to express boxed and unique closures in situations where
955
- the closure style can be unambiguously derived from the context. Most
956
- notably, when calling a higher-order function you do not have to use
957
- the long-hand syntax for the function you're passing, since the
958
- compiler can look at the argument type to find out what the parameter
959
- types are.
960
-
961
964
Because closures in Rust are so versatile, they are used often, and in
962
965
particular, functions taking closures are used as control structures
963
966
in much the same way as `if` or `loop`. For example, this one iterates
@@ -997,16 +1000,36 @@ of the parenthesis where it looks visually more like a typical block
997
1000
of code. The `do` expression is purely syntactic sugar for a call
998
1001
that takes a final closure argument.
999
1002
1000
- # For loops
1003
+ ### For loops
1001
1004
1002
- To allow breaking out of loops, many iteration functions, such as
1003
- `vec::each`, take a function that returns a boolean, and can return
1004
- `false` to break off iteration.
1005
+ `for` loops, like `do` expressions, allow functions to be used as
1006
+ as control structures. `for` loops can be used to treat functions
1007
+ with the proper signature as looping constructs, supporting
1008
+ `break`, `cont` and early returns.
1005
1009
1010
+ Take for example this `each` function that iterates over a vector,
1011
+ breaking early when the iteratee returns `false`:
1012
+
1013
+ ~~~~
1014
+ fn each<T>(v: &[T], f: fn(T) -> bool) {
1015
+ let mut n = 0;
1016
+ while n < v.len() {
1017
+ if !f(v[n]) {
1018
+ break;
1019
+ }
1020
+ n += 1;
1021
+ }
1022
+ }
1006
1023
~~~~
1007
- vec::each(~[2, 4, 8, 5, 16], |n| {
1024
+
1025
+ And using this function to iterate over a vector:
1026
+
1027
+ ~~~~
1028
+ # import each = vec::each;
1029
+ # import println = io::println;
1030
+ each(~[2, 4, 8, 5, 16], |n| {
1008
1031
if n % 2 != 0 {
1009
- io:: println("found odd number!");
1032
+ println("found odd number!");
1010
1033
false
1011
1034
} else { true }
1012
1035
});
@@ -1018,9 +1041,11 @@ return `true`, and `break` and `cont` can be used, much like in a
1018
1041
`while` loop, to explicitly return `false` or `true`.
1019
1042
1020
1043
~~~~
1021
- for vec::each(~[2, 4, 8, 5, 16]) |n| {
1044
+ # import each = vec::each;
1045
+ # import println = io::println;
1046
+ for each(~[2, 4, 8, 5, 16]) |n| {
1022
1047
if n % 2 != 0 {
1023
- io:: println("found odd number!");
1048
+ println("found odd number!");
1024
1049
break;
1025
1050
}
1026
1051
}
@@ -1032,14 +1057,16 @@ normally allowed in blocks, in a block that appears as the body of a
1032
1057
function, not just the loop body.
1033
1058
1034
1059
~~~~
1060
+ # import each = vec::each;
1035
1061
fn contains(v: ~[int], elt: int) -> bool {
1036
- for vec:: each(v) |x| {
1062
+ for each(v) |x| {
1037
1063
if (x == elt) { ret true; }
1038
1064
}
1039
1065
false
1040
1066
}
1041
1067
~~~~
1042
1068
1069
+
1043
1070
# Datatypes
1044
1071
1045
1072
Rust datatypes are, by default, immutable. The core datatypes of Rust
@@ -2579,6 +2606,8 @@ fn divide(a: float, b: float) -> float {
2579
2606
#[test]
2580
2607
#[should_fail]
2581
2608
fn divide_by_zero() { divide(1f, 0f); }
2609
+
2610
+ # fn main() { }
2582
2611
~~~~
2583
2612
2584
2613
To disable a test completely, add an `#[ignore]` attribute. Running a
0 commit comments