1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
% Vectors
A ‘vector’ is a dynamic or ‘growable’ array, implemented as the standard
library type [`Vec<T>`][vec]. The `T` means that we can have vectors
of any type (see the chapter on [generics][generic] for more).
Vectors always allocate their data on the heap.
You can create them with the `vec!` macro:
```rust
let v = vec![1, 2, 3, 4, 5]; // v: Vec<i32>
```
(Notice that unlike the `println!` macro we’ve used in the past, we use square
brackets `[]` with `vec!` macro. Rust allows you to use either in either
situation, this is just convention.)
There’s an alternate form of `vec!` for repeating an initial value:
```rust
let v = vec![0; 10]; // ten zeroes
```
Vectors store their contents as contiguous arrays of `T` on the heap. This means
that they must be able to know the size of `T` at compile time (that is, how
many bytes are needed to store a `T`?). The size of some things can't be known
at compile time. For these you'll have to store a pointer to that thing:
thankfully, the [`Box`][box] type works perfectly for this.
## Accessing elements
To get the value at a particular index in the vector, we use `[]`s:
```rust
let v = vec![1, 2, 3, 4, 5];
println!("The third element of v is {}", v[2]);
```
The indices count from `0`, so the third element is `v[2]`.
It’s also important to note that you must index with the `usize` type:
```ignore
let v = vec![1, 2, 3, 4, 5];
let i: usize = 0;
let j: i32 = 0;
// works
v[i];
// doesn’t
v[j];
```
Indexing with a non-`usize` type gives an error that looks like this:
```text
error: the trait bound `collections::vec::Vec<_> : core::ops::Index<i32>`
is not satisfied [E0277]
v[j];
^~~~
note: the type `collections::vec::Vec<_>` cannot be indexed by `i32`
error: aborting due to previous error
```
There’s a lot of punctuation in that message, but the core of it makes sense:
you cannot index with an `i32`.
## Out-of-bounds Access
If you try to access an index that doesn’t exist:
```ignore
let v = vec![1, 2, 3];
println!("Item 7 is {}", v[7]);
```
then the current thread will [panic] with a message like this:
```text
thread '<main>' panicked at 'index out of bounds: the len is 3 but the index is 7'
```
If you want to handle out-of-bounds errors without panicking, you can use
methods like [`get`][get] or [`get_mut`][get_mut] that return `None` when
given an invalid index:
```rust
let v = vec![1, 2, 3];
match v.get(7) {
Some(x) => println!("Item 7 is {}", x),
None => println!("Sorry, this vector is too short.")
}
```
## Iterating
Once you have a vector, you can iterate through its elements with `for`. There
are three versions:
```rust
let mut v = vec![1, 2, 3, 4, 5];
for i in &v {
println!("A reference to {}", i);
}
for i in &mut v {
println!("A mutable reference to {}", i);
}
for i in v {
println!("Take ownership of the vector and its element {}", i);
}
```
Note: You cannot use the vector again once you have iterated by taking ownership of the vector.
You can iterate the vector multiple times by taking a reference to the vector whilst iterating.
For example, the following code does not compile.
```rust,ignore
let v = vec![1, 2, 3, 4, 5];
for i in v {
println!("Take ownership of the vector and its element {}", i);
}
for i in v {
println!("Take ownership of the vector and its element {}", i);
}
```
Whereas the following works perfectly,
```rust
let v = vec![1, 2, 3, 4, 5];
for i in &v {
println!("This is a reference to {}", i);
}
for i in &v {
println!("This is a reference to {}", i);
}
```
Vectors have many more useful methods, which you can read about in [their
API documentation][vec].
[vec]: ../std/vec/index.html
[box]: ../std/boxed/index.html
[generic]: generics.html
[panic]: concurrency.html#panics
[get]: http://doc.rust-lang.org/std/vec/struct.Vec.html#method.get
[get_mut]: http://doc.rust-lang.org/std/vec/struct.Vec.html#method.get_mut
|