1. 1. Introduction
  2. 2. Getting Started
  3. 3. Tutorial: Guessing Game
  4. 4. Syntax and Semantics
    1. 4.1. Variable Bindings
    2. 4.2. Functions
    3. 4.3. Primitive Types
    4. 4.4. Comments
    5. 4.5. if
    6. 4.6. Loops
    7. 4.7. Vectors
    8. 4.8. Ownership
    9. 4.9. References and Borrowing
    10. 4.10. Lifetimes
    11. 4.11. Mutability
    12. 4.12. Structs
    13. 4.13. Enums
    14. 4.14. Match
    15. 4.15. Patterns
    16. 4.16. Method Syntax
    17. 4.17. Strings
    18. 4.18. Generics
    19. 4.19. Traits
    20. 4.20. Drop
    21. 4.21. if let
    22. 4.22. Trait Objects
    23. 4.23. Closures
    24. 4.24. Universal Function Call Syntax
    25. 4.25. Crates and Modules
    26. 4.26. `const` and `static`
    27. 4.27. Attributes
    28. 4.28. `type` aliases
    29. 4.29. Casting between types
    30. 4.30. Associated Types
    31. 4.31. Unsized Types
    32. 4.32. Operators and Overloading
    33. 4.33. Deref coercions
    34. 4.34. Macros
    35. 4.35. Raw Pointers
    36. 4.36. `unsafe`
  5. 5. Effective Rust
    1. 5.1. The Stack and the Heap
    2. 5.2. Testing
    3. 5.3. Conditional Compilation
    4. 5.4. Documentation
    5. 5.5. Iterators
    6. 5.6. Concurrency
    7. 5.7. Error Handling
    8. 5.8. Choosing your Guarantees
    9. 5.9. FFI
    10. 5.10. Borrow and AsRef
    11. 5.11. Release Channels
    12. 5.12. Using Rust without the standard library
  6. 6. Nightly Rust
    1. 6.1. Compiler Plugins
    2. 6.2. Inline Assembly
    3. 6.3. No stdlib
    4. 6.4. Intrinsics
    5. 6.5. Lang items
    6. 6.6. Advanced linking
    7. 6.7. Benchmark Tests
    8. 6.8. Box Syntax and Patterns
    9. 6.9. Slice Patterns
    10. 6.10. Associated Constants
    11. 6.11. Custom Allocators
  7. 7. Glossary
  8. 8. Syntax Index
  9. 9. Bibliography

Vectors

A ‘vector’ is a dynamic or ‘growable’ array, implemented as the standard library type Vec<T>. The T means that we can have vectors of any type (see the chapter on generics for more). Vectors always allocate their data on the heap. You can create them with the vec! macro:

let v = vec![1, 2, 3, 4, 5]; // v: Vec<i32>Run

(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:

let v = vec![0; 10]; // ten zeroesRun

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 type works perfectly for this.

Accessing elements

To get the value at a particular index in the vector, we use []s:

let v = vec![1, 2, 3, 4, 5];

println!("The third element of v is {}", v[2]);Run

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:

let v = vec![1, 2, 3, 4, 5];

let i: usize = 0;
let j: i32 = 0;

// works
v[i];

// doesn’t
v[j];Run

Indexing with a non-usize type gives an error that looks like this:

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:

let v = vec![1, 2, 3];
println!("Item 7 is {}", v[7]);Run

then the current thread will panic with a message like this:

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 or get_mut that return None when given an invalid index:

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.")
}Run

Iterating

Once you have a vector, you can iterate through its elements with for. There are three versions:

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);
}Run

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.

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);
}Run

Whereas the following works perfectly,

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);
}Run

Vectors have many more useful methods, which you can read about in their API documentation.