@@ -213,8 +213,8 @@ fn main() {
213
213
}
214
214
~~~~
215
215
216
- The ` let ` keyword, introduces a local variable. By default, variables
217
- are immutable. ` let mut ` can be used to introduce a local variable
216
+ The ` let ` keyword introduces a local variable. Variables are immutable
217
+ by default, so ` let mut ` can be used to introduce a local variable
218
218
that can be reassigned.
219
219
220
220
~~~~
@@ -229,14 +229,17 @@ while count < 10 {
229
229
230
230
Although Rust can almost always infer the types of local variables, it
231
231
can help readability to specify a variable's type by following it with
232
- a colon, then the type name. Local variables may shadow earlier
233
- declarations, making the earlier variables inaccessible.
232
+ a colon, then the type name.
234
233
235
234
~~~~
236
235
let my_favorite_value: float = 57.8;
237
236
let my_favorite_value: int = my_favorite_value as int;
238
237
~~~~
239
238
239
+ Local variables may shadow earlier declarations, as in the previous
240
+ example in which ` my_favorite_value ` is first declared as a ` float `
241
+ then a second ` my_favorite_value ` is declared as an int.
242
+
240
243
Rust identifiers follow the same rules as C; they start with an alphabetic
241
244
character or an underscore, and after that may contain any sequence of
242
245
alphabetic characters, numbers, or underscores. The preferred style is to
@@ -1632,8 +1635,9 @@ fn contains(v: &[int], elt: int) -> bool {
1632
1635
# Generics
1633
1636
1634
1637
Throughout this tutorial, we've been defining functions that act only on
1635
- single data types. With type parameters we can also define functions that
1636
- may be invoked on multiple types.
1638
+ specific data types. With type parameters we can also define functions whose
1639
+ arguments represent generic types, and which can be invoked with a variety
1640
+ of types. Consider a generic `map` function.
1637
1641
1638
1642
~~~~
1639
1643
fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
@@ -1653,7 +1657,7 @@ each other.
1653
1657
Inside a generic function, the names of the type parameters
1654
1658
(capitalized by convention) stand for opaque types. You can't look
1655
1659
inside them, but you can pass them around. Note that instances of
1656
- generic types are almost always passed by pointer. For example, the
1660
+ generic types are often passed by pointer. For example, the
1657
1661
parameter `function()` is supplied with a pointer to a value of type
1658
1662
`T` and not a value of type `T` itself. This ensures that the
1659
1663
function works with the broadest set of types possible, since some
@@ -1679,11 +1683,11 @@ These declarations produce valid types like `Set<int>`, `Stack<int>`
1679
1683
and `Maybe<int>`.
1680
1684
1681
1685
Generic functions in Rust are compiled to very efficient runtime code
1682
- through a process called _monomorphisation_. This big word just means
1683
- that, for each generic function you call, the compiler generates a
1684
- specialized version that is optimized specifically for the argument
1685
- types. In this respect Rust's generics have similar performance
1686
- characteristics to C++ templates.
1686
+ through a process called _monomorphisation_. This is a fancy way of
1687
+ saying that, for each generic function you call, the compiler
1688
+ generates a specialized version that is optimized specifically for the
1689
+ argument types. In this respect Rust's generics have similar
1690
+ performance characteristics to C++ templates.
1687
1691
1688
1692
## Traits
1689
1693
@@ -1748,23 +1752,23 @@ types by the compiler, and may not be overridden:
1748
1752
1749
1753
## Declaring and implementing traits
1750
1754
1751
- A trait consists of a set of methods, or may be empty, as is the case
1752
- with `Copy`, `Send`, and `Const`. A method is a function that
1753
- can be applied to a `self` value and a number of arguments, using the
1754
- dot notation: `self.foo(arg1, arg2)`.
1755
-
1756
- For example, we could declare the trait `Printable` for things that
1757
- can be printed to the console, with a single method:
1755
+ A trait consists of a set of methods, without bodies, or may be empty,
1756
+ as is the case with `Copy`, `Send`, and `Const`. For example, we could
1757
+ declare the trait `Printable` for things that can be printed to the
1758
+ console, with a single method:
1758
1759
1759
1760
~~~~
1760
1761
trait Printable {
1761
1762
fn print();
1762
1763
}
1763
1764
~~~~
1764
1765
1765
- To actually implement a trait for a given type, the `impl` form is
1766
- used. This defines implementations of `Printable` for the `int` and
1767
- `~str` types.
1766
+ Traits may be implemented for specific types with [impls]. An impl
1767
+ that implements a trait includes the name of the trait at the start of
1768
+ the definition, as in the following impls of `Printable` for `int`
1769
+ and `~str`.
1770
+
1771
+ [impls]: #functions-and-methods
1768
1772
1769
1773
~~~~
1770
1774
# trait Printable { fn print(); }
@@ -1780,14 +1784,10 @@ impl ~str: Printable {
1780
1784
# (~"foo").print();
1781
1785
~~~~
1782
1786
1783
- Given these, we may call `1.print()` to print `"1"`, or
1784
- `(~"foo").print()` to print `"foo"` again, as with . This is basically a form of
1785
- static overloading—when the Rust compiler sees the `print` method
1786
- call, it looks for an implementation that matches the type with a
1787
- method that matches the name, and simply calls that.
1788
-
1789
- Traits may themselves contain type parameters. A trait for
1790
- generalized sequence types might look like the following:
1787
+ Methods defined in an implementation of a trait may be called just as
1788
+ any other method, using dot notation, as in `1.print()`. Traits may
1789
+ themselves contain type parameters. A trait for generalized sequence
1790
+ types might look like the following:
1791
1791
1792
1792
~~~~
1793
1793
trait Seq<T> {
0 commit comments