Skip to content

Commit 80a4769

Browse files
committed
Update tutorial on generics. #4217
1 parent a59747c commit 80a4769

File tree

1 file changed

+19
-21
lines changed

1 file changed

+19
-21
lines changed

doc/tutorial.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,9 +1873,7 @@ is not defined for all Rust types. One reason is user-defined
18731873
destructors: copying a type that has a destructor could result in the
18741874
destructor running multiple times. Therefore, types with user-defined
18751875
destructors cannot be copied, either implicitly or explicitly, and
1876-
neither can types that own other types containing destructors (see the
1877-
section on [structs](#structs) for the actual mechanism for defining
1878-
destructors).
1876+
neither can types that own other types containing destructors.
18791877

18801878
This complicates handling of generic functions. If you have a type
18811879
parameter `T`, can you copy values of that type? In Rust, you can't,
@@ -1924,10 +1922,11 @@ types by the compiler, and may not be overridden:
19241922
> ***Note:*** These three traits were referred to as 'kinds' in earlier
19251923
> iterations of the language, and often still are.
19261924
1927-
There is also a special trait known as `Drop`. This trait defines one method
1928-
called `finalize`, which is automatically called when value of the a type that
1929-
implements this trait is destroyed, either because the value went out of scope
1930-
or because the garbage collector reclaimed it.
1925+
Additionally, the `Drop` trait is used to define destructors. This
1926+
trait defines one method called `finalize`, which is automatically
1927+
called when value of the a type that implements this trait is
1928+
destroyed, either because the value went out of scope or because the
1929+
garbage collector reclaimed it.
19311930

19321931
~~~
19331932
struct TimeBomb {
@@ -2023,7 +2022,7 @@ trait Eq {
20232022
fn equals(other: &self) -> bool;
20242023
}
20252024
2026-
// In an impl, self refers to the value of the receiver
2025+
// In an impl, `self` refers to the value of the receiver
20272026
impl int: Eq {
20282027
fn equals(other: &int) -> bool { *other == self }
20292028
}
@@ -2077,7 +2076,7 @@ the preferred way to use traits polymorphically.
20772076

20782077
This usage of traits is similar to Haskell type classes.
20792078

2080-
## Casting to a trait type and dynamic method dispatch
2079+
## Trait objects and dynamic method dispatch
20812080

20822081
The above allows us to define functions that polymorphically act on
20832082
values of a single unknown type that conforms to a given trait.
@@ -2099,7 +2098,8 @@ fn draw_all<T: Drawable>(shapes: ~[T]) {
20992098
You can call that on an array of circles, or an array of squares
21002099
(assuming those have suitable `Drawable` traits defined), but not on
21012100
an array containing both circles and squares. When such behavior is
2102-
needed, a trait name can alternately be used as a type.
2101+
needed, a trait name can alternately be used as a type, called
2102+
an _object_.
21032103

21042104
~~~~
21052105
# trait Drawable { fn draw(); }
@@ -2111,7 +2111,7 @@ fn draw_all(shapes: &[@Drawable]) {
21112111
In this example, there is no type parameter. Instead, the `@Drawable`
21122112
type denotes any managed box value that implements the `Drawable`
21132113
trait. To construct such a value, you use the `as` operator to cast a
2114-
value to a trait type:
2114+
value to an object:
21152115

21162116
~~~~
21172117
# type Circle = int; type Rectangle = bool;
@@ -2120,9 +2120,9 @@ value to a trait type:
21202120
# fn new_rectangle() -> Rectangle { true }
21212121
# fn draw_all(shapes: &[@Drawable]) {}
21222122
2123-
impl @Circle: Drawable { fn draw() { ... } }
2123+
impl Circle: Drawable { fn draw() { ... } }
21242124
2125-
impl @Rectangle: Drawable { fn draw() { ... } }
2125+
impl Rectangle: Drawable { fn draw() { ... } }
21262126
21272127
let c: @Circle = @new_circle();
21282128
let r: @Rectangle = @new_rectangle();
@@ -2131,12 +2131,13 @@ draw_all([c as @Drawable, r as @Drawable]);
21312131

21322132
We omit the code for `new_circle` and `new_rectangle`; imagine that
21332133
these just return `Circle`s and `Rectangle`s with a default size. Note
2134-
that, like strings and vectors, trait types have dynamic size and may
2135-
only be referred to via one of the pointer types. That's why the `impl` is
2136-
defined for `@Circle` and `@Rectangle` instead of for just `Circle`
2137-
and `Rectangle`. Other pointer types work as well.
2134+
that, like strings and vectors, objects have dynamic size and may
2135+
only be referred to via one of the pointer types.
2136+
Other pointer types work as well.
2137+
Casts to traits may only be done with compatible pointers so,
2138+
for example, an `@Circle` may not be cast to an `~Drawable`.
21382139

2139-
~~~{.xfail-test}
2140+
~~~
21402141
# type Circle = int; type Rectangle = int;
21412142
# trait Drawable { fn draw(); }
21422143
# impl int: Drawable { fn draw() {} }
@@ -2150,9 +2151,6 @@ let owny: ~Drawable = ~new_circle() as ~Drawable;
21502151
let stacky: &Drawable = &new_circle() as &Drawable;
21512152
~~~
21522153

2153-
> ***Note:*** Other pointer types actually _do not_ work here yet. This is
2154-
> an evolving corner of the language.
2155-
21562154
Method calls to trait types are _dynamically dispatched_. Since the
21572155
compiler doesn't know specifically which functions to call at compile
21582156
time, it uses a lookup table (also known as a vtable or dictionary) to

0 commit comments

Comments
 (0)