Skip to content

Commit 0027253

Browse files
committed
Import real content.
1 parent f354c8a commit 0027253

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+9377
-3
lines changed

src/doc/trpl/SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
* [Macros](macros.md)
5959
* [`unsafe` Code](unsafe-code.md)
6060
* [Nightly Rust](nightly-rust.md)
61-
* [Compiler Plugins](plugins.md)
61+
* [Compiler Plugins](compiler-plugins.md)
6262
* [Inline Assembly](inline-assembly.md)
6363
* [No stdlib](no-stdlib.md)
6464
* [Intrinsics](intrinsics.md)

src/doc/trpl/arrays.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
% Arrays
2+
3+
Like many programming languages, Rust has list types to represent a sequence of
4+
things. The most basic is the *array*, a fixed-size list of elements of the
5+
same type. By default, arrays are immutable.
6+
7+
```{rust}
8+
let a = [1, 2, 3]; // a: [i32; 3]
9+
let mut m = [1, 2, 3]; // mut m: [i32; 3]
10+
```
11+
12+
There's a shorthand for initializing each element of an array to the same
13+
value. In this example, each element of `a` will be initialized to `0`:
14+
15+
```{rust}
16+
let a = [0; 20]; // a: [i32; 20]
17+
```
18+
19+
Arrays have type `[T; N]`. We'll talk about this `T` notation later, when we
20+
cover generics.
21+
22+
You can get the number of elements in an array `a` with `a.len()`, and use
23+
`a.iter()` to iterate over them with a for loop. This code will print each
24+
number in order:
25+
26+
```{rust}
27+
let a = [1, 2, 3];
28+
29+
println!("a has {} elements", a.len());
30+
for e in a.iter() {
31+
println!("{}", e);
32+
}
33+
```
34+
35+
You can access a particular element of an array with *subscript notation*:
36+
37+
```{rust}
38+
let names = ["Graydon", "Brian", "Niko"]; // names: [&str; 3]
39+
40+
println!("The second name is: {}", names[1]);
41+
```
42+
43+
Subscripts start at zero, like in most programming languages, so the first name
44+
is `names[0]` and the second name is `names[1]`. The above example prints
45+
`The second name is: Brian`. If you try to use a subscript that is not in the
46+
array, you will get an error: array access is bounds-checked at run-time. Such
47+
errant access is the source of many bugs in other systems programming
48+
languages.

src/doc/trpl/associated-types.md

+202
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
% Associated Types
2+
3+
Associated types are a powerful part of Rust's type system. They're related to
4+
the idea of a 'type family', in other words, grouping multiple types together. That
5+
description is a bit abstract, so let's dive right into an example. If you want
6+
to write a `Graph` trait, you have two types to be generic over: the node type
7+
and the edge type. So you might write a trait, `Graph<N, E>`, that looks like
8+
this:
9+
10+
```rust
11+
trait Graph<N, E> {
12+
fn has_edge(&self, &N, &N) -> bool;
13+
fn edges(&self, &N) -> Vec<E>;
14+
// etc
15+
}
16+
```
17+
18+
While this sort of works, it ends up being awkward. For example, any function
19+
that wants to take a `Graph` as a parameter now _also_ needs to be generic over
20+
the `N`ode and `E`dge types too:
21+
22+
```rust,ignore
23+
fn distance<N, E, G: Graph<N, E>>(graph: &G, start: &N, end: &N) -> u32 { ... }
24+
```
25+
26+
Our distance calculation works regardless of our `Edge` type, so the `E` stuff in
27+
this signature is just a distraction.
28+
29+
What we really want to say is that a certain `E`dge and `N`ode type come together
30+
to form each kind of `Graph`. We can do that with associated types:
31+
32+
```rust
33+
trait Graph {
34+
type N;
35+
type E;
36+
37+
fn has_edge(&self, &Self::N, &Self::N) -> bool;
38+
fn edges(&self, &Self::N) -> Vec<Self::E>;
39+
// etc
40+
}
41+
```
42+
43+
Now, our clients can be abstract over a given `Graph`:
44+
45+
```rust,ignore
46+
fn distance<G: Graph>(graph: &G, start: &G::N, end: &G::N) -> uint { ... }
47+
```
48+
49+
No need to deal with the `E`dge type here!
50+
51+
Let's go over all this in more detail.
52+
53+
## Defining associated types
54+
55+
Let's build that `Graph` trait. Here's the definition:
56+
57+
```rust
58+
trait Graph {
59+
type N;
60+
type E;
61+
62+
fn has_edge(&self, &Self::N, &Self::N) -> bool;
63+
fn edges(&self, &Self::N) -> Vec<Self::E>;
64+
}
65+
```
66+
67+
Simple enough. Associated types use the `type` keyword, and go inside the body
68+
of the trait, with the functions.
69+
70+
These `type` declarations can have all the same thing as functions do. For example,
71+
if we wanted our `N` type to implement `Display`, so we can print the nodes out,
72+
we could do this:
73+
74+
```rust
75+
use std::fmt;
76+
77+
trait Graph {
78+
type N: fmt::Display;
79+
type E;
80+
81+
fn has_edge(&self, &Self::N, &Self::N) -> bool;
82+
fn edges(&self, &Self::N) -> Vec<Self::E>;
83+
}
84+
```
85+
86+
## Implementing associated types
87+
88+
Just like any trait, traits that use associated types use the `impl` keyword to
89+
provide implementations. Here's a simple implementation of Graph:
90+
91+
```rust
92+
# trait Graph {
93+
# type N;
94+
# type E;
95+
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
96+
# fn edges(&self, &Self::N) -> Vec<Self::E>;
97+
# }
98+
struct Node;
99+
100+
struct Edge;
101+
102+
struct MyGraph;
103+
104+
impl Graph for MyGraph {
105+
type N = Node;
106+
type E = Edge;
107+
108+
fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
109+
true
110+
}
111+
112+
fn edges(&self, n: &Node) -> Vec<Edge> {
113+
Vec::new()
114+
}
115+
}
116+
```
117+
118+
This silly implementation always returns `true` and an empty `Vec<Edge>`, but it
119+
gives you an idea of how to implement this kind of thing. We first need three
120+
`struct`s, one for the graph, one for the node, and one for the edge. If it made
121+
more sense to use a different type, that would work as well, we're just going to
122+
use `struct`s for all three here.
123+
124+
Next is the `impl` line, which is just like implementing any other trait.
125+
126+
From here, we use `=` to define our associated types. The name the trait uses
127+
goes on the left of the `=`, and the concrete type we're `impl`ementing this
128+
for goes on the right. Finally, we use the concrete types in our function
129+
declarations.
130+
131+
## Trait objects with associated types
132+
133+
There’s one more bit of syntax we should talk about: trait objects. If you
134+
try to create a trait object from an associated type, like this:
135+
136+
```rust,ignore
137+
# trait Graph {
138+
# type N;
139+
# type E;
140+
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
141+
# fn edges(&self, &Self::N) -> Vec<Self::E>;
142+
# }
143+
# struct Node;
144+
# struct Edge;
145+
# struct MyGraph;
146+
# impl Graph for MyGraph {
147+
# type N = Node;
148+
# type E = Edge;
149+
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
150+
# true
151+
# }
152+
# fn edges(&self, n: &Node) -> Vec<Edge> {
153+
# Vec::new()
154+
# }
155+
# }
156+
let graph = MyGraph;
157+
let obj = Box::new(graph) as Box<Graph>;
158+
```
159+
160+
You’ll get two errors:
161+
162+
```text
163+
error: the value of the associated type `E` (from the trait `main::Graph`) must
164+
be specified [E0191]
165+
let obj = Box::new(graph) as Box<Graph>;
166+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
167+
24:44 error: the value of the associated type `N` (from the trait
168+
`main::Graph`) must be specified [E0191]
169+
let obj = Box::new(graph) as Box<Graph>;
170+
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171+
```
172+
173+
We can’t create a trait object like this, because we don’t know the associated
174+
types. Instead, we can write this:
175+
176+
```rust
177+
# trait Graph {
178+
# type N;
179+
# type E;
180+
# fn has_edge(&self, &Self::N, &Self::N) -> bool;
181+
# fn edges(&self, &Self::N) -> Vec<Self::E>;
182+
# }
183+
# struct Node;
184+
# struct Edge;
185+
# struct MyGraph;
186+
# impl Graph for MyGraph {
187+
# type N = Node;
188+
# type E = Edge;
189+
# fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
190+
# true
191+
# }
192+
# fn edges(&self, n: &Node) -> Vec<Edge> {
193+
# Vec::new()
194+
# }
195+
# }
196+
let graph = MyGraph;
197+
let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
198+
```
199+
200+
The `N=Node` syntax allows us to provide a concrete type, `Node`, for the `N`
201+
type parameter. Same with `E=Edge`. If we didn’t proide this constraint, we
202+
couldn’t be sure which `impl` to match this trait object to.

src/doc/trpl/attributes.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
% Attributes
2+
3+
Coming Soon!

0 commit comments

Comments
 (0)