Merge pull request #4317 from apasel422/tutorial-fix
doc: make small corrections to tutorial
This commit is contained in:
commit
62d6031005
1 changed files with 83 additions and 81 deletions
120
doc/tutorial.md
120
doc/tutorial.md
|
@ -80,7 +80,7 @@ supported build environments that are most likely to work.
|
||||||
> "[getting started][wiki-start]" notes on the wiki. Even when using
|
> "[getting started][wiki-start]" notes on the wiki. Even when using
|
||||||
> the binary installer, the Windows build requires a MinGW installation,
|
> the binary installer, the Windows build requires a MinGW installation,
|
||||||
> the precise details of which are not discussed here. Finally, `rustc` may
|
> the precise details of which are not discussed here. Finally, `rustc` may
|
||||||
> need to be [referred to as `rustc.exe`][bug-3319]. It's a bummer, I
|
> need to be [referred to as `rustc.exe`][bug-3319]. It's a bummer, we
|
||||||
> know.
|
> know.
|
||||||
|
|
||||||
[bug-3319]: https://github.com/mozilla/rust/issues/3319
|
[bug-3319]: https://github.com/mozilla/rust/issues/3319
|
||||||
|
@ -114,7 +114,7 @@ for more information on them.
|
||||||
|
|
||||||
When complete, `make install` will place several programs into
|
When complete, `make install` will place several programs into
|
||||||
`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
|
`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
|
||||||
API-documentation tool, `cargo`, the Rust package manager,
|
API-documentation tool; `cargo`, the Rust package manager;
|
||||||
and `rusti`, the Rust REPL.
|
and `rusti`, the Rust REPL.
|
||||||
|
|
||||||
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
||||||
|
@ -181,10 +181,10 @@ in blocks delineated by curly braces; there are control structures
|
||||||
for branching and looping, like the familiar `if` and `while`; function
|
for branching and looping, like the familiar `if` and `while`; function
|
||||||
calls are written `myfunc(arg1, arg2)`; operators are written the same
|
calls are written `myfunc(arg1, arg2)`; operators are written the same
|
||||||
and mostly have the same precedence as in C; comments are again like C;
|
and mostly have the same precedence as in C; comments are again like C;
|
||||||
module names are separated with double-colon, `::`, as with C++.
|
module names are separated with double-colon (`::`) as with C++.
|
||||||
|
|
||||||
The main surface difference to be aware of is that the condition at
|
The main surface difference to be aware of is that the condition at
|
||||||
the head of control structures like `if` and `while` do not require
|
the head of control structures like `if` and `while` does not require
|
||||||
parentheses, while their bodies *must* be wrapped in
|
parentheses, while their bodies *must* be wrapped in
|
||||||
braces. Single-statement, unbraced bodies are not allowed.
|
braces. Single-statement, unbraced bodies are not allowed.
|
||||||
|
|
||||||
|
@ -226,12 +226,12 @@ let monster_size: int = 50;
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
Local variables may shadow earlier declarations, as in the previous example:
|
Local variables may shadow earlier declarations, as in the previous example:
|
||||||
`monster_size` was first declared as a `float`, and then then a second
|
`monster_size` was first declared as a `float`, and then a second
|
||||||
`monster_size` was declared as an int. If you were to actually compile this
|
`monster_size` was declared as an `int`. If you were to actually compile this
|
||||||
example, though, the compiler will determine that the second `monster_size` is
|
example, though, the compiler would determine that the second `monster_size` is
|
||||||
unused and issue a warning (because this situation is likely to indicate a
|
unused and issue a warning (because this situation is likely to indicate a
|
||||||
programmer error). For occasions where unused variables are intentional, their
|
programmer error). For occasions where unused variables are intentional, their
|
||||||
name may be prefixed with an underscore to silence the warning, like `let
|
names may be prefixed with an underscore to silence the warning, like `let
|
||||||
_monster_size = 50;`.
|
_monster_size = 50;`.
|
||||||
|
|
||||||
Rust identifiers start with an alphabetic
|
Rust identifiers start with an alphabetic
|
||||||
|
@ -292,7 +292,7 @@ branch has a different value, and `price` gets the value of the branch that
|
||||||
was taken.
|
was taken.
|
||||||
|
|
||||||
In short, everything that's not a declaration (declarations are `let` for
|
In short, everything that's not a declaration (declarations are `let` for
|
||||||
variables, `fn` for functions, and any top-level named items such as
|
variables; `fn` for functions; and any top-level named items such as
|
||||||
[traits](#traits), [enum types](#enums), and [constants](#constants)) is an
|
[traits](#traits), [enum types](#enums), and [constants](#constants)) is an
|
||||||
expression, including function bodies.
|
expression, including function bodies.
|
||||||
|
|
||||||
|
@ -306,8 +306,8 @@ fn is_four(x: int) -> bool {
|
||||||
|
|
||||||
## Primitive types and literals
|
## Primitive types and literals
|
||||||
|
|
||||||
There are general signed and unsigned integer types, `int`, and `uint`,
|
There are general signed and unsigned integer types, `int` and `uint`,
|
||||||
as well as 8-, 16-, 32-, and 64-bit variations, `i8`, `u16`, etc.
|
as well as 8-, 16-, 32-, and 64-bit variants, `i8`, `u16`, etc.
|
||||||
Integers can be written in decimal (`144`), hexadecimal (`0x90`), or
|
Integers can be written in decimal (`144`), hexadecimal (`0x90`), or
|
||||||
binary (`0b10010000`) base. Each integral type has a corresponding literal
|
binary (`0b10010000`) base. Each integral type has a corresponding literal
|
||||||
suffix that can be used to indicate the type of a literal: `i` for `int`,
|
suffix that can be used to indicate the type of a literal: `i` for `int`,
|
||||||
|
@ -326,14 +326,14 @@ let c = 100u; // c is a uint
|
||||||
let d = 1000i32; // d is an i32
|
let d = 1000i32; // d is an i32
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
There are three floating point types, `float`, `f32`, and `f64`.
|
There are three floating-point types: `float`, `f32`, and `f64`.
|
||||||
Floating point numbers are written `0.0`, `1e6`, or `2.1e-4`.
|
Floating-point numbers are written `0.0`, `1e6`, or `2.1e-4`.
|
||||||
Like integers, floating point literals are inferred to the correct type.
|
Like integers, floating-point literals are inferred to the correct type.
|
||||||
Suffixes `f`, `f32` and `f64` can be used to create literals of a specific type.
|
Suffixes `f`, `f32`, and `f64` can be used to create literals of a specific type.
|
||||||
|
|
||||||
The keywords `true` and `false` produce literals of type `bool`.
|
The keywords `true` and `false` produce literals of type `bool`.
|
||||||
|
|
||||||
Characters, the `char` type, are 4-byte unicode codepoints,
|
Characters, the `char` type, are four-byte Unicode codepoints,
|
||||||
whose literals are written between single quotes, as in `'x'`.
|
whose literals are written between single quotes, as in `'x'`.
|
||||||
Just like C, Rust understands a number of character escapes, using the backslash
|
Just like C, Rust understands a number of character escapes, using the backslash
|
||||||
character, such as `\n`, `\r`, and `\t`. String literals,
|
character, such as `\n`, `\r`, and `\t`. String literals,
|
||||||
|
@ -345,8 +345,8 @@ The nil type, written `()`, has a single value, also written `()`.
|
||||||
## Operators
|
## Operators
|
||||||
|
|
||||||
Rust's set of operators contains very few surprises. Arithmetic is done with
|
Rust's set of operators contains very few surprises. Arithmetic is done with
|
||||||
`*`, `/`, `%`, `+`, and `-` (multiply, divide, take remainder, add, subtract). `-` is
|
`*`, `/`, `%`, `+`, and `-` (multiply, divide, take remainder, add, and subtract). `-` is
|
||||||
also a unary prefix operator that negates numbers. As in C, the bit operators
|
also a unary prefix operator that negates numbers. As in C, the bitwise operators
|
||||||
`>>`, `<<`, `&`, `|`, and `^` are also supported.
|
`>>`, `<<`, `&`, `|`, and `^` are also supported.
|
||||||
|
|
||||||
Note that, if applied to an integer value, `!` flips all the bits (like `~` in
|
Note that, if applied to an integer value, `!` flips all the bits (like `~` in
|
||||||
|
@ -444,7 +444,7 @@ match my_number {
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
Unlike in C, there is no 'falling through' between arms: only one arm
|
Unlike in C, there is no "falling through" between arms: only one arm
|
||||||
executes, and it doesn't have to explicitly `break` out of the
|
executes, and it doesn't have to explicitly `break` out of the
|
||||||
construct when it is finished.
|
construct when it is finished.
|
||||||
|
|
||||||
|
@ -494,7 +494,7 @@ fn angle(vector: (float, float)) -> float {
|
||||||
A variable name in a pattern matches any value, *and* binds that name
|
A variable name in a pattern matches any value, *and* binds that name
|
||||||
to the value of the matched value inside of the arm's action. Thus, `(0f,
|
to the value of the matched value inside of the arm's action. Thus, `(0f,
|
||||||
y)` matches any tuple whose first element is zero, and binds `y` to
|
y)` matches any tuple whose first element is zero, and binds `y` to
|
||||||
the second element. `(x, y)` matches any tuple, and binds both
|
the second element. `(x, y)` matches any two-element tuple, and binds both
|
||||||
elements to variables.
|
elements to variables.
|
||||||
|
|
||||||
Any `match` arm can have a guard clause (written `if EXPR`), called a
|
Any `match` arm can have a guard clause (written `if EXPR`), called a
|
||||||
|
@ -575,7 +575,7 @@ With a value of such a type, you can do `mystack.head += 1`. If `mut` were
|
||||||
omitted from the type, such an assignment would result in a type error.
|
omitted from the type, such an assignment would result in a type error.
|
||||||
|
|
||||||
`match` patterns destructure structs. The basic syntax is
|
`match` patterns destructure structs. The basic syntax is
|
||||||
`Name {fieldname: pattern, ...}`:
|
`Name { fieldname: pattern, ... }`:
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
# struct Point { x: float, y: float }
|
# struct Point { x: float, y: float }
|
||||||
|
@ -589,7 +589,7 @@ match mypoint {
|
||||||
In general, the field names of a struct do not have to appear in the same
|
In general, the field names of a struct do not have to appear in the same
|
||||||
order they appear in the type. When you are not interested in all
|
order they appear in the type. When you are not interested in all
|
||||||
the fields of a struct, a struct pattern may end with `, _` (as in
|
the fields of a struct, a struct pattern may end with `, _` (as in
|
||||||
`Name {field1, _}`) to indicate that you're ignoring all other fields.
|
`Name { field1, _ }`) to indicate that you're ignoring all other fields.
|
||||||
Additionally, struct fields have a shorthand matching form that simply
|
Additionally, struct fields have a shorthand matching form that simply
|
||||||
reuses the field name as the binding name.
|
reuses the field name as the binding name.
|
||||||
|
|
||||||
|
@ -618,15 +618,15 @@ A value of this type is either a `Circle`, in which case it contains a
|
||||||
`Point` struct and a float, or a `Rectangle`, in which case it contains
|
`Point` struct and a float, or a `Rectangle`, in which case it contains
|
||||||
two `Point` structs. The run-time representation of such a value
|
two `Point` structs. The run-time representation of such a value
|
||||||
includes an identifier of the actual form that it holds, much like the
|
includes an identifier of the actual form that it holds, much like the
|
||||||
'tagged union' pattern in C, but with better static guarantees.
|
"tagged union" pattern in C, but with better static guarantees.
|
||||||
|
|
||||||
The above declaration will define a type `Shape` that can refer to
|
The above declaration will define a type `Shape` that can refer to
|
||||||
such shapes, and two functions, `Circle` and `Rectangle`, which can be
|
such shapes, and two functions, `Circle` and `Rectangle`, which can be
|
||||||
used to construct values of the type (taking arguments of the
|
used to construct values of the type (taking arguments of the
|
||||||
specified types). So `Circle(Point {x: 0f, y: 0f}, 10f)` is the way to
|
specified types). So `Circle(Point { x: 0f, y: 0f }, 10f)` is the way to
|
||||||
create a new circle.
|
create a new circle.
|
||||||
|
|
||||||
Enum variants need not have type parameters. This `enum` declaration,
|
Enum variants need not have parameters. This `enum` declaration,
|
||||||
for example, is equivalent to a C enum:
|
for example, is equivalent to a C enum:
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
|
@ -659,7 +659,7 @@ variant does not have a discriminator, it defaults to 0. For example,
|
||||||
the value of `North` is 0, `East` is 1, `South` is 2, and `West` is 3.
|
the value of `North` is 0, `East` is 1, `South` is 2, and `West` is 3.
|
||||||
|
|
||||||
When an enum is C-like, you can apply the `as` cast operator to
|
When an enum is C-like, you can apply the `as` cast operator to
|
||||||
convert it to its discriminator value as an int.
|
convert it to its discriminator value as an `int`.
|
||||||
|
|
||||||
<a name="single_variant_enum"></a>
|
<a name="single_variant_enum"></a>
|
||||||
|
|
||||||
|
@ -710,7 +710,7 @@ patterns, as in this definition of `area`:
|
||||||
fn area(sh: Shape) -> float {
|
fn area(sh: Shape) -> float {
|
||||||
match sh {
|
match sh {
|
||||||
Circle(_, size) => float::consts::pi * size * size,
|
Circle(_, size) => float::consts::pi * size * size,
|
||||||
Rectangle(Point {x, y}, Point {x: x2, y: y2}) => (x2 - x) * (y2 - y)
|
Rectangle(Point { x, y }, Point { x: x2, y: y2 }) => (x2 - x) * (y2 - y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
@ -721,14 +721,14 @@ introduction form, nullary enum patterns are written without
|
||||||
parentheses.
|
parentheses.
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
# struct Point {x: float, y: float}
|
# struct Point { x: float, y: float }
|
||||||
# enum Direction { North, East, South, West }
|
# enum Direction { North, East, South, West }
|
||||||
fn point_from_direction(dir: Direction) -> Point {
|
fn point_from_direction(dir: Direction) -> Point {
|
||||||
match dir {
|
match dir {
|
||||||
North => Point {x: 0f, y: 1f},
|
North => Point { x: 0f, y: 1f },
|
||||||
East => Point {x: 1f, y: 0f},
|
East => Point { x: 1f, y: 0f },
|
||||||
South => Point {x: 0f, y: -1f},
|
South => Point { x: 0f, y: -1f },
|
||||||
West => Point {x: -1f, y: 0f}
|
West => Point { x: -1f, y: 0f }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
@ -737,7 +737,7 @@ Enum variants may also be structs. For example:
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
# use core::float;
|
# use core::float;
|
||||||
# struct Point {x: float, y: float}
|
# struct Point { x: float, y: float }
|
||||||
# fn square(x: float) -> float { x * x }
|
# fn square(x: float) -> float { x * x }
|
||||||
enum Shape {
|
enum Shape {
|
||||||
Circle { center: Point, radius: float },
|
Circle { center: Point, radius: float },
|
||||||
|
@ -752,6 +752,7 @@ fn area(sh: Shape) -> float {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
## Tuples
|
## Tuples
|
||||||
|
|
||||||
Tuples in Rust behave exactly like structs, except that their fields
|
Tuples in Rust behave exactly like structs, except that their fields
|
||||||
|
@ -800,7 +801,7 @@ fn line(a: int, b: int, x: int) -> int {
|
||||||
|
|
||||||
The `return` keyword immediately returns from the body of a function. It
|
The `return` keyword immediately returns from the body of a function. It
|
||||||
is optionally followed by an expression to return. A function can
|
is optionally followed by an expression to return. A function can
|
||||||
also return a value by having its top level block produce an
|
also return a value by having its top-level block produce an
|
||||||
expression.
|
expression.
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
|
@ -834,7 +835,7 @@ assert () == oops(5, 3, 1);
|
||||||
|
|
||||||
As with `match` expressions and `let` bindings, function arguments support
|
As with `match` expressions and `let` bindings, function arguments support
|
||||||
pattern destructuring. Like `let`, argument patterns must be irrefutable,
|
pattern destructuring. Like `let`, argument patterns must be irrefutable,
|
||||||
as in this example that unpacks a tuple and returns it.
|
as in this example that unpacks the first value from a tuple and returns it.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
fn first((value, _): (int, float)) -> int { value }
|
fn first((value, _): (int, float)) -> int { value }
|
||||||
|
@ -917,7 +918,7 @@ aggregate types like structs and enums, so as to represent these types
|
||||||
as pointers to heap memory by default. In contrast, Rust, like C and
|
as pointers to heap memory by default. In contrast, Rust, like C and
|
||||||
C++, represents such types directly. Another way to say this is that
|
C++, represents such types directly. Another way to say this is that
|
||||||
aggregate data in Rust are *unboxed*. This means that if you `let x =
|
aggregate data in Rust are *unboxed*. This means that if you `let x =
|
||||||
Point {x: 1f, y: 1f};`, you are creating a struct on the stack. If you
|
Point { x: 1f, y: 1f };`, you are creating a struct on the stack. If you
|
||||||
then copy it into a data structure, you copy the entire struct, not
|
then copy it into a data structure, you copy the entire struct, not
|
||||||
just a pointer.
|
just a pointer.
|
||||||
|
|
||||||
|
@ -927,7 +928,7 @@ those with mutable fields, it can be useful to have a single copy on
|
||||||
the stack or on the heap, and refer to that through a pointer.
|
the stack or on the heap, and refer to that through a pointer.
|
||||||
|
|
||||||
Rust supports several types of pointers. The safe pointer types are
|
Rust supports several types of pointers. The safe pointer types are
|
||||||
`@T` for managed boxes allocated on the local heap, `~T`, for
|
`@T`, for managed boxes allocated on the local heap, `~T`, for
|
||||||
uniquely-owned boxes allocated on the exchange heap, and `&T`, for
|
uniquely-owned boxes allocated on the exchange heap, and `&T`, for
|
||||||
borrowed pointers, which may point to any memory, and whose lifetimes
|
borrowed pointers, which may point to any memory, and whose lifetimes
|
||||||
are governed by the call stack.
|
are governed by the call stack.
|
||||||
|
@ -941,7 +942,7 @@ All pointer types can be dereferenced with the `*` unary operator.
|
||||||
|
|
||||||
## Managed boxes
|
## Managed boxes
|
||||||
|
|
||||||
Managed boxes are pointers to heap-allocated, garbage collected
|
Managed boxes are pointers to heap-allocated, garbage-collected
|
||||||
memory. Applying the unary `@` operator to an expression creates a
|
memory. Applying the unary `@` operator to an expression creates a
|
||||||
managed box. The resulting box contains the result of the
|
managed box. The resulting box contains the result of the
|
||||||
expression. Copying a managed box, as happens during assignment, only
|
expression. Copying a managed box, as happens during assignment, only
|
||||||
|
@ -1037,7 +1038,8 @@ As an example, consider a simple struct type, `Point`:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
struct Point {
|
struct Point {
|
||||||
x: float, y: float
|
x: float,
|
||||||
|
y: float
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
|
@ -1047,9 +1049,9 @@ contains a point, but allocated in a different location:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
# struct Point { x: float, y: float }
|
# struct Point { x: float, y: float }
|
||||||
let on_the_stack : Point = Point {x: 3.0, y: 4.0};
|
let on_the_stack : Point = Point { x: 3.0, y: 4.0 };
|
||||||
let managed_box : @Point = @Point {x: 5.0, y: 1.0};
|
let managed_box : @Point = @Point { x: 5.0, y: 1.0 };
|
||||||
let owned_box : ~Point = ~Point {x: 7.0, y: 9.0};
|
let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 };
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Suppose we wanted to write a procedure that computed the distance
|
Suppose we wanted to write a procedure that computed the distance
|
||||||
|
@ -1078,9 +1080,9 @@ Now we can call `compute_distance()` in various ways:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
# struct Point{ x: float, y: float };
|
# struct Point{ x: float, y: float };
|
||||||
# let on_the_stack : Point = Point {x: 3.0, y: 4.0};
|
# let on_the_stack : Point = Point { x: 3.0, y: 4.0 };
|
||||||
# let managed_box : @Point = @Point {x: 5.0, y: 1.0};
|
# let managed_box : @Point = @Point { x: 5.0, y: 1.0 };
|
||||||
# let owned_box : ~Point = ~Point {x: 7.0, y: 9.0};
|
# let owned_box : ~Point = ~Point { x: 7.0, y: 9.0 };
|
||||||
# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }
|
# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }
|
||||||
compute_distance(&on_the_stack, managed_box);
|
compute_distance(&on_the_stack, managed_box);
|
||||||
compute_distance(managed_box, owned_box);
|
compute_distance(managed_box, owned_box);
|
||||||
|
@ -1090,14 +1092,14 @@ Here the `&` operator is used to take the address of the variable
|
||||||
`on_the_stack`; this is because `on_the_stack` has the type `Point`
|
`on_the_stack`; this is because `on_the_stack` has the type `Point`
|
||||||
(that is, a struct value) and we have to take its address to get a
|
(that is, a struct value) and we have to take its address to get a
|
||||||
value. We also call this _borrowing_ the local variable
|
value. We also call this _borrowing_ the local variable
|
||||||
`on_the_stack`, because we are created an alias: that is, another
|
`on_the_stack`, because we are creating an alias: that is, another
|
||||||
route to the same data.
|
route to the same data.
|
||||||
|
|
||||||
In the case of the boxes `managed_box` and `owned_box`, however, no
|
In the case of the boxes `managed_box` and `owned_box`, however, no
|
||||||
explicit action is necessary. The compiler will automatically convert
|
explicit action is necessary. The compiler will automatically convert
|
||||||
a box like `@point` or `~point` to a borrowed pointer like
|
a box like `@point` or `~point` to a borrowed pointer like
|
||||||
`&point`. This is another form of borrowing; in this case, the
|
`&point`. This is another form of borrowing; in this case, the
|
||||||
contents of the managed/owned box is being lent out.
|
contents of the managed/owned box are being lent out.
|
||||||
|
|
||||||
Whenever a value is borrowed, there are some limitations on what you
|
Whenever a value is borrowed, there are some limitations on what you
|
||||||
can do with the original. For example, if the contents of a variable
|
can do with the original. For example, if the contents of a variable
|
||||||
|
@ -1157,7 +1159,7 @@ let area = (*rect).area();
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
To combat this ugliness the dot operator applies _automatic pointer
|
To combat this ugliness the dot operator applies _automatic pointer
|
||||||
dereferencing_ to the receiver (the value on the left hand side of the
|
dereferencing_ to the receiver (the value on the left-hand side of the
|
||||||
dot), so in most cases, explicitly dereferencing the receiver is not necessary.
|
dot), so in most cases, explicitly dereferencing the receiver is not necessary.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
|
@ -1199,7 +1201,7 @@ pointers to vectors are also called 'slices'.
|
||||||
// A fixed-size stack vector
|
// A fixed-size stack vector
|
||||||
let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot];
|
let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot];
|
||||||
|
|
||||||
// A borrowed pointer to stack allocated vector
|
// A borrowed pointer to stack-allocated vector
|
||||||
let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine];
|
let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine];
|
||||||
|
|
||||||
// A local heap (managed) vector of crayons
|
// A local heap (managed) vector of crayons
|
||||||
|
@ -1526,7 +1528,7 @@ do spawn() || {
|
||||||
}
|
}
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
Look at all those bars and parentheses - that's two empty argument
|
Look at all those bars and parentheses -- that's two empty argument
|
||||||
lists back to back. Since that is so unsightly, empty argument lists
|
lists back to back. Since that is so unsightly, empty argument lists
|
||||||
may be omitted from `do` expressions.
|
may be omitted from `do` expressions.
|
||||||
|
|
||||||
|
@ -1605,7 +1607,7 @@ fn contains(v: &[int], elt: int) -> bool {
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
Notice that, because `each` passes each value by borrowed pointer,
|
Notice that, because `each` passes each value by borrowed pointer,
|
||||||
the iteratee needs to dereference it before using.
|
the iteratee needs to dereference it before using it.
|
||||||
In these situations it can be convenient to lean on Rust's
|
In these situations it can be convenient to lean on Rust's
|
||||||
argument patterns to bind `x` to the actual value, not the pointer.
|
argument patterns to bind `x` to the actual value, not the pointer.
|
||||||
|
|
||||||
|
@ -1727,7 +1729,7 @@ s.draw_borrowed();
|
||||||
// ... and dereferenced
|
// ... and dereferenced
|
||||||
(& &s).draw_borrowed();
|
(& &s).draw_borrowed();
|
||||||
|
|
||||||
// ... and dereferenced, and borrowed, and
|
// ... and dereferenced and borrowed
|
||||||
(&@~s).draw_borrowed();
|
(&@~s).draw_borrowed();
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
@ -1813,7 +1815,7 @@ enum Option<T> {
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
These declarations can be instantiated to valid types like `Set<int>`,
|
These declarations can be instantiated to valid types like `Set<int>`,
|
||||||
`Stack<int>` and `Option<int>`.
|
`Stack<int>`, and `Option<int>`.
|
||||||
|
|
||||||
The last type in that example, `Option`, appears frequently in Rust code.
|
The last type in that example, `Option`, appears frequently in Rust code.
|
||||||
Because Rust does not have null pointers (except in unsafe code), we need
|
Because Rust does not have null pointers (except in unsafe code), we need
|
||||||
|
@ -1822,7 +1824,7 @@ combination of arguments of the appropriate types. The usual way is to write
|
||||||
a function that returns `Option<T>` instead of `T`.
|
a function that returns `Option<T>` instead of `T`.
|
||||||
|
|
||||||
~~~~
|
~~~~
|
||||||
# struct Point {x: float, y: float}
|
# struct Point { x: float, y: float }
|
||||||
# enum Shape { Circle(Point, float), Rectangle(Point, Point) }
|
# enum Shape { Circle(Point, float), Rectangle(Point, Point) }
|
||||||
fn radius(shape: Shape) -> Option<float> {
|
fn radius(shape: Shape) -> Option<float> {
|
||||||
match shape {
|
match shape {
|
||||||
|
@ -1892,7 +1894,7 @@ While most traits can be defined and implemented by user code, three
|
||||||
traits are automatically derived and implemented for all applicable
|
traits are automatically derived and implemented for all applicable
|
||||||
types by the compiler, and may not be overridden:
|
types by the compiler, and may not be overridden:
|
||||||
|
|
||||||
* `Copy` - Types that can be copied: either implicitly, or explicitly with the
|
* `Copy` - Types that can be copied, either implicitly, or explicitly with the
|
||||||
`copy` operator. All types are copyable unless they have destructors or
|
`copy` operator. All types are copyable unless they have destructors or
|
||||||
contain types with destructors.
|
contain types with destructors.
|
||||||
|
|
||||||
|
@ -1914,7 +1916,7 @@ garbage collector reclaimed it.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
struct TimeBomb {
|
struct TimeBomb {
|
||||||
explosivity: uint,
|
explosivity: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TimeBomb : Drop {
|
impl TimeBomb : Drop {
|
||||||
|
@ -2103,9 +2105,9 @@ fn draw_all<T: Drawable>(shapes: ~[T]) {
|
||||||
# draw_all(~[c]);
|
# draw_all(~[c]);
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
You can call that on an array of circles, or an array of squares
|
You can call that on an array of circles, or an array of rectangles
|
||||||
(assuming those have suitable `Drawable` traits defined), but not on
|
(assuming those have suitable `Drawable` traits defined), but not on
|
||||||
an array containing both circles and squares. When such behavior is
|
an array containing both circles and rectangles. When such behavior is
|
||||||
needed, a trait name can alternately be used as a type, called
|
needed, a trait name can alternately be used as a type, called
|
||||||
an _object_.
|
an _object_.
|
||||||
|
|
||||||
|
@ -2320,7 +2322,7 @@ fn main() {
|
||||||
|
|
||||||
The unit of independent compilation in Rust is the crate: rustc
|
The unit of independent compilation in Rust is the crate: rustc
|
||||||
compiles a single crate at a time, from which it produces either a
|
compiles a single crate at a time, from which it produces either a
|
||||||
library or executable.
|
library or an executable.
|
||||||
|
|
||||||
When compiling a single `.rs` source file, the file acts as the whole crate.
|
When compiling a single `.rs` source file, the file acts as the whole crate.
|
||||||
You can compile it with the `--lib` compiler switch to create a shared
|
You can compile it with the `--lib` compiler switch to create a shared
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue