Vectors

Create a vector

let vec: Vec<u32> = Vec::new();

Note that we added a type annotation here. Because we aren’t inserting any values into this vector, Rust doesn’t know what kind of elements we intend to store.

More often, you’ll create a Vec<T> with initial values and Rust will infer the type of value you want to store, so you rarely need to do this type annotation. Rust conveniently provides the vec! macro, which will create a new vector that holds the values you give it.

let vec = Vec![1, 2, 3];

Update a vector

let mut vec: Vec<u32> = Vec::new();
vec.push(1);
vec.push(2);

Read an element in the vector.

// Use the indexing.
let val: &i32 = &vec[0];
let val = vec.get(0); // Returns Option<i32>

It is recommended to use the get method instead of the plain indexing because the get method will return None if the requested item does not exist while indexing may panic if the index is out of bound.

let val: &i32 = &vec[100]; // ERROR

if let Some(val) = vec.get(100) {
	println!("OK! The value is {}", val);
} else {
	println!("Non-existing!");
}

When the program has a valid reference, the borrow checker enforces the ownership and borrowing rules to ensure this reference and any other references to the contents of the vector remain valid. Likewise, if the vector has immutable reference to itself, the vector cannot be updated by push method because it may require allocation and copy of the memory. In this case, the reference may points to a freed memory space that causes UD.

let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6); // Won't compile here.
println!("The first element is: {}", first);

error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
  --> src/main.rs:19:3
   |
18 |   let first = &v[0];
   |                - immutable borrow occurs here
19 |   v.push(6); // Won't compile here.
   |   ^^^^^^^^^ mutable borrow occurs here
20 |   println!("The first element is: {}", first);
   |                                        ----- immutable borrow later used here

For more information about this error, try `rustc --explain E0502`.

Iterate over the vector

let vec: Vec<i32> = vec![1, 2, 3];
for v in &vec {
	println!("{}", v);
}

// We can also iterate over mutable references to each element in a 
// mutable vector in order to make changes to all the elements.
for v in &mut vec {
	*v = *v + 1;
}

Strings

Fortunately, Rust finally provides us with a literally String type rather than the char buffer in C++ (so ugly). String types in Rust will support encoding and many other textual operations.

We’ll first define what we mean by the term string. Rust has only one string type in the core language, which is the string slice str that is usually seen in its borrowed form &str, also known as the string literal, as same as the const char* type.