Skip to content

Commit fafce9a

Browse files
killerswanbrson
authored andcommitted
More looking at the tutorial, small changes
1 parent 2dfd822 commit fafce9a

File tree

1 file changed

+61
-59
lines changed

1 file changed

+61
-59
lines changed

doc/tutorial.md

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ something—in which case you'll have embedded it in a bigger statement.
329329
# fn foo() -> bool { true }
330330
# fn bar() -> bool { true }
331331
# fn baz() -> bool { true }
332-
333332
// `let` is not an expression, so it is semi-colon terminated;
334333
let x = foo();
335334
@@ -711,8 +710,8 @@ Structs can be destructured in `match` patterns. The basic syntax is
711710
# struct Point { x: float, y: float }
712711
# let mypoint = Point { x: 0.0, y: 0.0 };
713712
match mypoint {
714-
Point { x: 0.0, y: y } => { io::println(y.to_str()); }
715-
Point { x: x, y: y } => { io::println(x.to_str() + " " + y.to_str()); }
713+
Point { x: 0.0, y: yy } => { io::println(yy.to_str()); }
714+
Point { x: xx, y: yy } => { io::println(xx.to_str() + " " + yy.to_str()); }
716715
}
717716
~~~~
718717

@@ -802,7 +801,7 @@ dereference (`*`) unary operator:
802801

803802
~~~~
804803
# enum GizmoId = int;
805-
let my_gizmo_id = GizmoId(10);
804+
let my_gizmo_id: GizmoId = GizmoId(10);
806805
let id_int: int = *my_gizmo_id;
807806
~~~~
808807

@@ -863,12 +862,8 @@ back to [later](#modules-and-crates)). They are introduced with the
863862
the return type follows the arrow.
864863

865864
~~~~
866-
fn repeat(string: &str, count: int) -> ~str {
867-
let mut result = ~"";
868-
for count.times {
869-
result += string;
870-
}
871-
return result;
865+
fn line(a: int, b: int, x: int) -> int {
866+
return a*x + b;
872867
}
873868
~~~~
874869

@@ -889,10 +884,8 @@ fn int_to_str(i: int) -> ~str {
889884
~~~~
890885

891886
~~~~
892-
# const copernicus: int = 0;
893-
fn int_to_str(i: int) -> ~str {
894-
if i == copernicus { ~"tube sock" }
895-
else { ~"violin" }
887+
fn line(a: int, b: int, x: int) -> int {
888+
a*x + b
896889
}
897890
~~~~
898891

@@ -906,6 +899,16 @@ fn do_nothing_the_hard_way() -> () { return (); }
906899
fn do_nothing_the_easy_way() { }
907900
~~~~
908901

902+
Ending the function with a semicolon like so is equivalent to returning `()`.
903+
904+
~~~~
905+
fn line(a: int, b: int, x: int) -> int { a*x + b }
906+
fn oops(a: int, b: int, x: int) -> () { a*x + b; }
907+
908+
assert 8 == line(5,3,1);
909+
assert () == oops(5,3,1);
910+
~~~~
911+
909912
Methods are like functions, except that they are defined for a specific
910913
'self' type (like 'this' in C++). Calling a method is done with
911914
dot notation, as in `my_vec.len()`. Methods may be defined on most
@@ -1005,7 +1008,7 @@ easy for programmers to reason about. Heap isolation has the
10051008
additional benefit that garbage collection must only be done
10061009
per-heap. Rust never "stops the world" to reclaim memory.
10071010

1008-
Complete isolation of heaps between tasks implies that any data
1011+
Complete isolation of heaps between tasks would, however, mean that any data
10091012
transferred between tasks must be copied. While this is a fine and
10101013
useful way to implement communication between tasks, it is also very
10111014
inefficient for large data structures. Because of this, Rust also
@@ -1117,6 +1120,9 @@ If you really want to copy a unique box you must say so explicitly.
11171120
~~~~
11181121
let x = ~10;
11191122
let y = copy x;
1123+
1124+
let z = *x + *y;
1125+
assert z = 20;
11201126
~~~~
11211127

11221128
This is where the 'move' operator comes in. It is similar to
@@ -1125,9 +1131,11 @@ from `x` to `y`, without violating the constraint that it only has a
11251131
single owner (if you used assignment instead of the move operator, the
11261132
box would, in principle, be copied).
11271133

1128-
~~~~
1134+
~~~~ {.ignore}
11291135
let x = ~10;
11301136
let y = move x;
1137+
1138+
let z = *x + *y; // would cause an error: use of moved variable: `x`
11311139
~~~~
11321140

11331141
Owned boxes, when they do not contain any managed boxes, can be sent
@@ -1265,7 +1273,7 @@ also done with square brackets (zero-based):
12651273
# BananaMania, Beaver, Bittersweet };
12661274
# fn draw_scene(c: Crayon) { }
12671275
1268-
let crayons = [BananaMania, Beaver, Bittersweet];
1276+
let crayons: [Crayon] = [BananaMania, Beaver, Bittersweet];
12691277
match crayons[0] {
12701278
Bittersweet => draw_scene(crayons[0]),
12711279
_ => ()
@@ -1282,7 +1290,7 @@ elements. Mutable vector literals are written `[mut]` (empty) or `[mut
12821290
# Aquamarine, Asparagus, AtomicTangerine,
12831291
# BananaMania, Beaver, Bittersweet };
12841292
1285-
let crayons = [mut BananaMania, Beaver, Bittersweet];
1293+
let crayons: [mut Crayon] = [mut BananaMania, Beaver, Bittersweet];
12861294
crayons[0] = AtomicTangerine;
12871295
~~~~
12881296
@@ -1318,8 +1326,8 @@ my_crayons += your_crayons;
13181326
> not well supported yet, owned vectors are often the most
13191327
> usable.
13201328
1321-
Strings are simply vectors of `[u8]`, though they have a distinct
1322-
type. They support most of the same allocation aptions as
1329+
Strings are implemented with vectors of `[u8]`, though they have a distinct
1330+
type. They support most of the same allocation options as
13231331
vectors, though the string literal without a storage sigil, e.g.
13241332
`"foo"` is treated differently than a comparable vector (`[foo]`).
13251333
Where
@@ -1328,7 +1336,7 @@ Where
13281336
// A plain string is a slice to read-only (static) memory
13291337
let stack_crayons: &str = "Almond, AntiqueBrass, Apricot";
13301338

1331-
// The same thing, but without
1339+
// The same thing, but with the `&`
13321340
let stack_crayons: &str = &"Almond, AntiqueBrass, Apricot";
13331341

13341342
// A local heap (managed) string
@@ -1511,9 +1519,12 @@ call_twice(bare_function);
15111519
15121520
## Do syntax
15131521
1514-
Closures in Rust are frequently used in combination with higher-order
1515-
functions to simulate control structures like `if` and
1516-
`loop`. Consider this function that iterates over a vector of
1522+
The `do` expression is syntactic sugar for use with functions which
1523+
take a closure as a final argument, because closures in Rust
1524+
are so frequently used in combination with higher-order
1525+
functions.
1526+
1527+
Consider this function which iterates over a vector of
15171528
integers, passing in a pointer to each integer in the vector:
15181529
15191530
~~~~
@@ -1558,8 +1569,7 @@ do each(&[1, 2, 3]) |n| {
15581569
The call is prefixed with the keyword `do` and, instead of writing the
15591570
final closure inside the argument list it is moved outside of the
15601571
parenthesis where it looks visually more like a typical block of
1561-
code. The `do` expression is purely syntactic sugar for a call that
1562-
takes a final closure argument.
1572+
code.
15631573
15641574
`do` is often used for task spawning.
15651575
@@ -1653,6 +1663,10 @@ fn contains(v: &[int], elt: int) -> bool {
16531663
16541664
`for` syntax only works with stack closures.
16551665
1666+
> ***Note:*** This is, essentially, a special loop protocol:
1667+
> the keywords `break`, `loop`, and `return` work, in varying degree,
1668+
> with `while`, `loop`, `do`, and `for` constructs.
1669+
16561670
# Generics
16571671
16581672
Throughout this tutorial, we've been defining functions that act only on
@@ -2057,6 +2071,9 @@ The compiler will now look for `poultry/chicken.rs` and
20572071
and `poultry::turkey`. You can also provide a `poultry.rs` to add
20582072
content to the `poultry` module itself.
20592073

2074+
The compiler then builds the crate as a platform-specific shared library or
2075+
executable which can be distributed.
2076+
20602077
## Using other crates
20612078

20622079
Having compiled a crate that contains the `#[crate_type = "lib"]`
@@ -2111,22 +2128,22 @@ Now for something that you can actually compile yourself. We have
21112128
these two files:
21122129

21132130
~~~~
2114-
// mylib.rs
2115-
#[link(name = "mylib", vers = "1.0")];
2116-
fn world() -> ~str { ~"world" }
2131+
// world.rs
2132+
#[link(name = "world", vers = "1.0")];
2133+
fn explore() -> ~str { ~"world" }
21172134
~~~~
21182135

21192136
~~~~ {.ignore}
21202137
// main.rs
2121-
extern mod mylib;
2122-
fn main() { io::println(~"hello " + mylib::world()); }
2138+
extern mod world;
2139+
fn main() { io::println(~"hello " + world::explore()); }
21232140
~~~~
21242141

21252142
Now compile and run like this (adjust to your platform if necessary):
21262143

21272144
~~~~ {.notrust}
2128-
> rustc --lib mylib.rs
2129-
> rustc main.rs -L .
2145+
> rustc --lib world.rs # compiles libworld-94839cbfe144198-1.0.so
2146+
> rustc main.rs -L . # compiles main
21302147
> ./main
21312148
"hello world"
21322149
~~~~
@@ -2146,12 +2163,14 @@ fn main() {
21462163
}
21472164
~~~~
21482165

2166+
21492167
It is also possible to import just the name of a module (`use
21502168
std::list;`, then use `list::find`), to import all identifiers exported
21512169
by a given module (`use io::*`), or to import a specific set
21522170
of identifiers (`use math::{min, max, pi}`).
21532171

2154-
You can rename an identifier when importing using the `=` operator:
2172+
Rust uses different namespaces for modules, types, and values. You
2173+
can also rename an identifier when importing using the `=` operator:
21552174

21562175
~~~~
21572176
use prnt = io::println;
@@ -2175,27 +2194,6 @@ This defines a rock-solid encryption algorithm. Code outside of the
21752194
module can refer to the `enc::encrypt` and `enc::decrypt` identifiers
21762195
just fine, but it does not have access to `enc::super_secret_number`.
21772196

2178-
## Namespaces
2179-
2180-
Rust uses three different namespaces: one for modules, one for types,
2181-
and one for values. This means that this code is valid:
2182-
2183-
~~~~
2184-
#[legacy_exports]
2185-
mod buffalo {
2186-
type buffalo = int;
2187-
fn buffalo<buffalo>(+buffalo: buffalo) -> buffalo { buffalo }
2188-
}
2189-
fn main() {
2190-
let buffalo: buffalo::buffalo = 1;
2191-
buffalo::buffalo::<buffalo::buffalo>(buffalo::buffalo(buffalo));
2192-
}
2193-
~~~~
2194-
2195-
You don't want to write things like that, but it *is* very practical
2196-
to not have to worry about name clashes between types, values, and
2197-
modules.
2198-
21992197
## Resolution
22002198

22012199
The resolution process in Rust simply goes up the chain of contexts,
@@ -2211,21 +2209,25 @@ Identifiers can shadow each other. In this program, `x` is of type
22112209
type MyType = ~str;
22122210
fn main() {
22132211
type MyType = int;
2214-
let x: MyType;
2212+
let x: MyType = 17;
22152213
}
22162214
~~~~
22172215

22182216
An `use` directive will only import into the namespaces for which
22192217
identifiers are actually found. Consider this example:
22202218

22212219
~~~~
2222-
mod foo { fn bar() {} }
2223-
fn baz() {
2224-
let bar = 10u;
2220+
mod foo {
2221+
fn bar() {}
2222+
}
2223+
2224+
fn main() {
2225+
let bar = 10;
22252226
22262227
{
22272228
use foo::bar;
22282229
let quux = bar;
2230+
assert quux == 10;
22292231
}
22302232
}
22312233
~~~~

0 commit comments

Comments
 (0)