@@ -1807,10 +1807,13 @@ fn contains(v: &[int], elt: int) -> bool {
1807
1807
1808
1808
# Generics
1809
1809
1810
- Throughout this tutorial, we've been defining functions that act only on
1811
- specific data types. With type parameters we can also define functions whose
1812
- arguments represent generic types, and which can be invoked with a variety
1813
- of types. Consider a generic ` map ` function.
1810
+ Throughout this tutorial, we've been defining functions that act only
1811
+ on specific data types. With type parameters we can also define
1812
+ functions whose arguments have generic types, and which can be invoked
1813
+ with a variety of types. Consider a generic ` map ` function, which
1814
+ takes a function ` function ` and a vector ` vector ` and returns a new
1815
+ vector consisting of the result of applying ` function ` to each element
1816
+ of ` vector ` :
1814
1817
1815
1818
~~~~
1816
1819
fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
@@ -1824,17 +1827,18 @@ fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
1824
1827
1825
1828
When defined with type parameters, as denoted by ` <T, U> ` , this
1826
1829
function can be applied to any type of vector, as long as the type of
1827
- ` function ` 's argument and the type of the vector's content agree with
1830
+ ` function ` 's argument and the type of the vector's contents agree with
1828
1831
each other.
1829
1832
1830
1833
Inside a generic function, the names of the type parameters
1831
- (capitalized by convention) stand for opaque types. You can't look
1832
- inside them, but you can pass them around. Note that instances of
1833
- generic types are often passed by pointer. For example, the
1834
- parameter ` function() ` is supplied with a pointer to a value of type
1835
- ` T ` and not a value of type ` T ` itself. This ensures that the
1836
- function works with the broadest set of types possible, since some
1837
- types are expensive or illegal to copy and pass by value.
1834
+ (capitalized by convention) stand for opaque types. All you can do
1835
+ with instances of these types is pass them around: you can't apply any
1836
+ operations to them or pattern-match on them. Note that instances of
1837
+ generic types are often passed by pointer. For example, the parameter
1838
+ ` function() ` is supplied with a pointer to a value of type ` T ` and not
1839
+ a value of type ` T ` itself. This ensures that the function works with
1840
+ the broadest set of types possible, since some types are expensive or
1841
+ illegal to copy and pass by value.
1838
1842
1839
1843
Generic ` type ` , ` struct ` , and ` enum ` declarations follow the same pattern:
1840
1844
@@ -1852,15 +1856,16 @@ enum Maybe<T> {
1852
1856
}
1853
1857
~~~~
1854
1858
1855
- These declarations produce valid types like ` Set<int> ` , ` Stack<int> `
1856
- and ` Maybe<int> ` .
1859
+ These declarations can be instantiated to valid types like ` Set<int> ` ,
1860
+ ` Stack<int> ` and ` Maybe<int> ` .
1857
1861
1858
- Generic functions in Rust are compiled to very efficient runtime code
1859
- through a process called _ monomorphisation_ . This is a fancy way of
1860
- saying that, for each generic function you call, the compiler
1861
- generates a specialized version that is optimized specifically for the
1862
- argument types. In this respect Rust's generics have similar
1863
- performance characteristics to C++ templates.
1862
+ The Rust compiler compiles generic functions very efficiently by
1863
+ * monomorphizing* them. * Monomorphization* is a fancy name for a simple
1864
+ idea: generate a separate copy of each generic function at each call
1865
+ site where it is called, a copy that is specialized to the argument
1866
+ types and can thus be optimized specifically for them. In this
1867
+ respect, Rust's generics have similar performance characteristics to
1868
+ C++ templates.
1864
1869
1865
1870
## Traits
1866
1871
@@ -1869,15 +1874,19 @@ are very limited. After all, since the function doesn't know what
1869
1874
types it is operating on, it can't safely modify or query their
1870
1875
values. This is where _ traits_ come into play. Traits are Rust's most
1871
1876
powerful tool for writing polymorphic code. Java developers will see
1872
- in them aspects of Java interfaces, and Haskellers will notice their
1873
- similarities to type classes.
1874
-
1875
- As motivation, let us consider copying in Rust. Perhaps surprisingly,
1876
- the copy operation is not defined for all Rust types. In
1877
- particular, types with user-defined destructors cannot be copied,
1878
- either implicitly or explicitly, and neither can types that own other
1879
- types containing destructors (the actual mechanism for defining
1880
- destructors will be discussed elsewhere).
1877
+ them as similar to Java interfaces, and Haskellers will notice their
1878
+ similarities to type classes. Rust's traits are a form of * bounded
1879
+ polymorphism* : a trait is a way of limiting the set of possible types
1880
+ that a type parameter could refer to.
1881
+
1882
+ As motivation, let us consider copying in Rust. The ` copy ` operation
1883
+ is not defined for all Rust types. One reason is user-defined
1884
+ destructors: copying a type that has a destructor could result in the
1885
+ destructor running multiple times. Therefore, types with user-defined
1886
+ destructors cannot be copied, either implicitly or explicitly, and
1887
+ neither can types that own other types containing destructors (see the
1888
+ section on [ structs] ( #structs ) for the actual mechanism for defining
1889
+ destructors).
1881
1890
1882
1891
This complicates handling of generic functions. If you have a type
1883
1892
parameter ` T ` , can you copy values of that type? In Rust, you can't,
@@ -1890,8 +1899,8 @@ fn head_bad<T>(v: &[T]) -> T {
1890
1899
}
1891
1900
~~~~
1892
1901
1893
- We can tell the compiler though that the ` head ` function is only for
1894
- copyable types with the ` Copy ` trait.
1902
+ However, we can tell the compiler that the ` head ` function is only for
1903
+ copyable types: that is, those that have the ` Copy ` trait.
1895
1904
1896
1905
~~~~
1897
1906
// This does
@@ -1903,14 +1912,17 @@ fn head<T: Copy>(v: &[T]) -> T {
1903
1912
This says that we can call ` head ` on any type ` T ` as long as that type
1904
1913
implements the ` Copy ` trait. When instantiating a generic function,
1905
1914
you can only instantiate it with types that implement the correct
1906
- trait, so you could not apply ` head ` to a type with a destructor.
1915
+ trait, so you could not apply ` head ` to a type with a
1916
+ destructor. (` Copy ` is a special trait that is built in to the
1917
+ compiler, making it possible for the compiler to enforce this
1918
+ restriction.)
1907
1919
1908
1920
While most traits can be defined and implemented by user code, three
1909
1921
traits are automatically derived and implemented for all applicable
1910
1922
types by the compiler, and may not be overridden:
1911
1923
1912
- * ` Copy ` - Types that can be copied, either implicitly, or using the
1913
- ` copy ` expression . All types are copyable unless they are classes
1924
+ * ` Copy ` - Types that can be copied: either implicitly, or explicitly with the
1925
+ ` copy ` operator . All types are copyable unless they are classes
1914
1926
with destructors or otherwise contain classes with destructors.
1915
1927
1916
1928
* ` Send ` - Sendable (owned) types. All types are sendable unless they
@@ -1957,7 +1969,7 @@ impl ~str: Printable {
1957
1969
# (~"foo").print();
1958
1970
~~~~
1959
1971
1960
- Methods defined in an implementation of a trait may be called just as
1972
+ Methods defined in an implementation of a trait may be called just like
1961
1973
any other method, using dot notation, as in ` 1.print() ` . Traits may
1962
1974
themselves contain type parameters. A trait for generalized sequence
1963
1975
types might look like the following:
@@ -1979,14 +1991,14 @@ impl<T> ~[T]: Seq<T> {
1979
1991
The implementation has to explicitly declare the type parameter that
1980
1992
it binds, ` T ` , before using it to specify its trait type. Rust
1981
1993
requires this declaration because the ` impl ` could also, for example,
1982
- specify an implementation of ` Seq<int> ` . The trait type -- appearing
1983
- after the colon in the ` impl ` -- * refers* to a type, rather than
1994
+ specify an implementation of ` Seq<int> ` . The trait type ( appearing
1995
+ after the colon in the ` impl ` ) * refers* to a type, rather than
1984
1996
defining one.
1985
1997
1986
1998
The type parameters bound by a trait are in scope in each of the
1987
1999
method declarations. So, re-declaring the type parameter
1988
- ` T ` as an explicit type parameter for ` len ` -- in either the trait or
1989
- the impl -- would be a compile-time error.
2000
+ ` T ` as an explicit type parameter for ` len ` , in either the trait or
2001
+ the impl, would be a compile-time error.
1990
2002
1991
2003
Within a trait definition, ` self ` is a special type that you can think
1992
2004
of as a type parameter. An implementation of the trait for any given
@@ -2006,16 +2018,17 @@ impl int: Eq {
2006
2018
}
2007
2019
~~~~
2008
2020
2009
- Notice that in the trait definition, ` equals ` takes a ` self ` type
2010
- argument, whereas , in the impl, ` equals ` takes an ` int ` type argument,
2011
- and uses ` self ` as the name of the receiver (analogous to the ` this ` pointer
2012
- in C++).
2021
+ Notice that in the trait definition, ` equals ` takes a parameter of
2022
+ type ` self ` . In contrast , in the ` impl ` , ` equals ` takes a parameter of
2023
+ type ` int ` , and uses ` self ` as the name of the receiver (analogous to
2024
+ the ` this ` pointer in C++).
2013
2025
2014
2026
## Bounded type parameters and static method dispatch
2015
2027
2016
- Traits give us a language for talking about the abstract capabilities
2017
- of types, and we can use this to place _ bounds_ on type parameters,
2018
- so that we can then operate on generic types.
2028
+ Traits give us a language for defining predicates on types, or
2029
+ abstract properties that types can have. We can use this language to
2030
+ define _ bounds_ on type parameters, so that we can then operate on
2031
+ generic types.
2019
2032
2020
2033
~~~~
2021
2034
# trait Printable { fn print(); }
@@ -2026,14 +2039,14 @@ fn print_all<T: Printable>(printable_things: ~[T]) {
2026
2039
}
2027
2040
~~~~
2028
2041
2029
- By declaring ` T ` as conforming to the ` Printable ` trait (as we earlier
2030
- did with ` Copy ` ), it becomes possible to call methods from that trait
2031
- on values of that type inside the function. It will also cause a
2042
+ Declaring ` T ` as conforming to the ` Printable ` trait (as we earlier
2043
+ did with ` Copy ` ) makes it possible to call methods from that trait
2044
+ on values of type ` T ` inside the function. It will also cause a
2032
2045
compile-time error when anyone tries to call ` print_all ` on an array
2033
2046
whose element type does not have a ` Printable ` implementation.
2034
2047
2035
2048
Type parameters can have multiple bounds by separating them with spaces,
2036
- as in this version of ` print_all ` that makes copies of elements.
2049
+ as in this version of ` print_all ` that copies elements.
2037
2050
2038
2051
~~~
2039
2052
# trait Printable { fn print(); }
@@ -2083,10 +2096,10 @@ fn draw_all(shapes: &[@Drawable]) {
2083
2096
}
2084
2097
~~~~
2085
2098
2086
- In this example there is no type parameter. Instead, the ` @Drawable `
2087
- type is used to refer to any managed box value that implements the
2088
- ` Drawable ` trait. To construct such a value, you use the ` as ` operator
2089
- to cast a value to a trait type:
2099
+ In this example, there is no type parameter. Instead, the ` @Drawable `
2100
+ type denotes any managed box value that implements the ` Drawable `
2101
+ trait. To construct such a value, you use the ` as ` operator to cast a
2102
+ value to a trait type:
2090
2103
2091
2104
~~~~
2092
2105
# type Circle = int; type Rectangle = bool;
@@ -2104,10 +2117,12 @@ let r: @Rectangle = @new_rectangle();
2104
2117
draw_all(&[c as @Drawable, r as @Drawable]);
2105
2118
~~~~
2106
2119
2107
- Note that, like strings and vectors, trait types have dynamic size
2108
- and may only be used via one of the pointer types. In turn, the
2109
- ` impl ` is defined for ` @Circle ` and ` @Rectangle ` instead of for
2110
- just ` Circle ` and ` Rectangle ` . Other pointer types work as well.
2120
+ We omit the code for ` new_circle ` and ` new_rectangle ` ; imagine that
2121
+ these just return ` Circle ` s and ` Rectangle ` s with a default size. Note
2122
+ that, like strings and vectors, trait types have dynamic size and may
2123
+ only be referred to via one of the pointer types. That's why the ` impl ` is
2124
+ defined for ` @Circle ` and ` @Rectangle ` instead of for just ` Circle `
2125
+ and ` Rectangle ` . Other pointer types work as well.
2111
2126
2112
2127
~~~ {.xfail-test}
2113
2128
# type Circle = int; type Rectangle = int;
@@ -2123,13 +2138,13 @@ let owny: ~Drawable = ~new_circle() as ~Drawable;
2123
2138
let stacky: &Drawable = &new_circle() as &Drawable;
2124
2139
~~~
2125
2140
2126
- > *** Note:*** Other pointer types actually _ do not_ work here. This is
2141
+ > *** Note:*** Other pointer types actually _ do not_ work here yet . This is
2127
2142
> an evolving corner of the language.
2128
2143
2129
2144
Method calls to trait types are _ dynamically dispatched_ . Since the
2130
2145
compiler doesn't know specifically which functions to call at compile
2131
- time it uses a lookup table (vtable) to decide at runtime which
2132
- method to call.
2146
+ time it uses a lookup table (also known as a vtable or dictionary) to
2147
+ select the method to call at runtime .
2133
2148
2134
2149
This usage of traits is similar to Java interfaces.
2135
2150
@@ -2170,17 +2185,18 @@ fn chicken_farmer() {
2170
2185
~~~
2171
2186
2172
2187
These farm animal functions have a new keyword, ` pub ` , attached to
2173
- them. This is a visibility modifier that allows item to be accessed
2174
- outside of the module in which they are declared, using ` :: ` , as in
2175
- ` farm::chicken ` . Items, like ` fn ` , ` struct ` , etc. are private by
2176
- default.
2188
+ them. The ` pub ` keyword modifies an item's visibility, making it
2189
+ visible outside its containing module. An expression with ` :: ` , like
2190
+ ` farm::chicken ` , can name an item outside of its containing
2191
+ module. Items, such as those declared with ` fn ` , ` struct ` , ` enum ` ,
2192
+ ` type ` , or ` const ` , are module-private by default.
2177
2193
2178
2194
Visibility restrictions in Rust exist only at module boundaries. This
2179
- is quite different from most object-oriented languages that also enforce
2180
- restrictions on objects themselves. That's not to say that Rust doesn't
2181
- support encapsulation - both struct fields and methods can be private -
2182
- but it is at the module level, not the class level. Note that fields
2183
- and methods are _ public_ by default.
2195
+ is quite different from most object-oriented languages that also
2196
+ enforce restrictions on objects themselves. That's not to say that
2197
+ Rust doesn't support encapsulation: both struct fields and methods can
2198
+ be private. But this encapsulation is at the module level, not the
2199
+ struct level. Note that fields and methods are _ public_ by default.
2184
2200
2185
2201
~~~
2186
2202
mod farm {
@@ -2220,7 +2236,7 @@ fn main() {
2220
2236
2221
2237
## Crates
2222
2238
2223
- The unit of independent compilation in Rust is the crate - rustc
2239
+ The unit of independent compilation in Rust is the crate: rustc
2224
2240
compiles a single crate at a time, from which it produces either a
2225
2241
library or executable.
2226
2242
@@ -2294,38 +2310,40 @@ fn main() { bar::baz(); }
2294
2310
2295
2311
## Using other crates
2296
2312
2297
- Having compiled a crate into a library you can use it in another crate
2298
- with an ` extern mod ` directive. ` extern mod ` can appear at the top of
2299
- a crate file or at the top of modules. It will cause the compiler to
2300
- look in the library search path (which you can extend with ` -L `
2301
- switch) for a compiled Rust library with the right name, then add a
2302
- module with that crate's name into the local scope.
2313
+ The ` extern mod ` directive lets you use a crate (once it's been
2314
+ compiled into a library) from inside another crate. ` extern mod ` can
2315
+ appear at the top of a crate file or at the top of modules. It will
2316
+ cause the compiler to look in the library search path (which you can
2317
+ extend with the ` -L ` switch) for a compiled Rust library with the
2318
+ right name, then add a module with that crate's name into the local
2319
+ scope.
2303
2320
2304
2321
For example, ` extern mod std ` links the [ standard library] .
2305
2322
2306
2323
[ standard library ] : std/index.html
2307
2324
2308
- When a comma-separated list of name/value pairs is given after `extern
2309
- mod` , these are matched against the attributes provided in the ` link`
2310
- attribute of the crate file, and a crate is only used when the two
2311
- match. A ` name ` value can be given to override the name used to search
2312
- for the crate.
2325
+ When a comma-separated list of name/value pairs appears after `extern
2326
+ mod`, the compiler front-end matches these pairs against the
2327
+ attributes provided in the ` link ` attribute of the crate file. The
2328
+ front-end will only select this crate for use if the actual pairs
2329
+ match the declared attributes. You can provide a ` name ` value to
2330
+ override the name used to search for the crate.
2313
2331
2314
2332
Our example crate declared this set of ` link ` attributes:
2315
2333
2316
2334
~~~~ {.xfail-test}
2317
2335
#[link(name = "farm", vers = "2.5", author = "mjh")];
2318
2336
~~~~
2319
2337
2320
- Which can then be linked with any (or all) of the following:
2338
+ Which you can then link with any (or all) of the following:
2321
2339
2322
2340
~~~~ {.xfail-test}
2323
2341
extern mod farm;
2324
2342
extern mod my_farm (name = "farm", vers = "2.5");
2325
2343
extern mod my_auxiliary_farm (name = "farm", author = "mjh");
2326
2344
~~~~
2327
2345
2328
- If any of the requested metadata does not match then the crate
2346
+ If any of the requested metadata do not match, then the crate
2329
2347
will not be compiled successfully.
2330
2348
2331
2349
## A minimal example
@@ -2361,7 +2379,7 @@ a hash representing the crate metadata.
2361
2379
2362
2380
## The core library
2363
2381
2364
- The Rust [ core] library acts as the language runtime and contains
2382
+ The Rust [ core] library is the language runtime and contains
2365
2383
required memory management and task scheduling code as well as a
2366
2384
number of modules necessary for effective usage of the primitive
2367
2385
types. Methods on [ vectors] and [ strings] , implementations of most
0 commit comments