Rewrite vectors

pull/67/head
Dhghomon 4 years ago committed by GitHub
parent b84dfe615b
commit 9486909565
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1849,7 +1849,7 @@ You can also have an **inclusive** range, which means it includes the last numbe
## Vectors
In the same way that we have `&str` and `String`, we have arrays and vectors. Arrays are faster with less functionality, and vectors are slower with more functionality. The type is written `Vec`.
In the same way that we have `&str` and `String`, we have arrays and vectors. Arrays are faster with less functionality, and vectors are slower with more functionality. (Of course, Rust is always very fast so vectors are not slow, just slow*er* than arrays.) The type is written `Vec`, and you can also just call it a "vec".
There are two main ways to declare a vector. One is like with `String` using `new`:
@ -1867,7 +1867,12 @@ fn main() {
}
```
Or you can just declare the type.
You can see that a `Vec` always has something else inside it, and that's what the `<>` (angle brackets) are for. A `Vec<String>` is a vector with one or more `String`s. You can also have more types inside. For example:
- `Vec<(i32, i32)>` this is a `Vec` where each item is a tuple: `(i32, i32)`.
- `Vec<Vec<String>>` this is a `Vec` that has `Vec`s of `Strings`. Say for example you wanted to save your favourite book as a `Vec<String>`. Then you do it again with another book, and get another `Vec<String>`. To hold both books, you would put them into another `Vec` and that would be a `Vec<Vec<String>>`.
Instead of using `.push()` to make Rust decide the type, you can just declare the type.
```rust
fn main() {
@ -1886,14 +1891,14 @@ fn main() {
}
```
The type is `Vec<i32>`. You call it a "vec of i32s". And a `Vec<String>` is a "vec of strings". And a `Vec<Vec<String>>` is a "vec of a vec of strings".
The type is `Vec<i32>`. You call it a "Vec of i32s". And a `Vec<String>` is a "Vec of strings". And a `Vec<Vec<String>>` is a "Vec of a vec of strings".
You can slice a vector too, just like in an array.
```rust
fn main() {
let vec_of_ten = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Everything is the same except we added vec!
// Everything is the same as above except we added vec!.
let three_to_five = &vec_of_ten[2..5];
let start_at_two = &vec_of_ten[1..];
let end_at_five = &vec_of_ten[..5];
@ -1906,26 +1911,35 @@ everything: {:?}", three_to_five, start_at_two, end_at_five, everything);
}
```
Because a vec is slower than an array, we can use some methods to make it faster. A vec has a **capacity**, which means the space given to the vector. If you add more to a vector than its capacity, it will make its capacity double and copy the items into the new space. This is called reallocation.
Because a vec is slower than an array, we can use some methods to make it faster. A vec has a **capacity**, which means the space given to the vector. When you push a new item on the vector, it gets closer and closer to the capacity. Then if you go past the capacity, it will make its capacity double and copy the items into the new space. This is called reallocation. We'll use a method called `.capacity()` to look at the capacity of a vector as we add items to it.
For example:
```rust
fn main() {
let mut num_vec = Vec::new();
println!("{}", num_vec.capacity()); // 0 elements: prints 0
num_vec.push('a'); // add one character
println!("{}", num_vec.capacity()); // prints 1
println!("{}", num_vec.capacity()); // 1 element: prints 4. Vecs with 1 item always start with capacity 4
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 2
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 4. It has three elements, but capacity is 4
num_vec.push('a'); // add one more
num_vec.push('a'); // add one more // Now we have 5 elements
println!("{}", num_vec.capacity()); // Now capacity is 8
println!("{}", num_vec.capacity()); // 4 elements: still prints 4.
num_vec.push('a'); // add one more
println!("{}", num_vec.capacity()); // prints 8. We have 5 elements, but it doubled 4 to 8 to make space
}
```
So this vector has three reallocations: 1 to 2, 2 to 4, and 4 to 8. We can make it faster:
This prints:
```text
0
4
4
8
```
So this vector has three reallocations: 0 to 4, and 4 to 8. We can make it faster:
```rust
fn main() {
@ -1942,7 +1956,7 @@ fn main() {
}
```
This vector has 0 reallocations, which is better. So if you think you know how many elements you need, you can use `Vec::with_capacity()` to make it faster.
This vector has 0 reallocations, which is better. So if you think you know how many elements you need, you can use `Vec::with_capacity()` to make it faster.
You remember that you can use `.into()` to make a `&str` into a `String`. You can also use it to make an array into a `Vec`. You have to tell `.into()` that you want a `Vec`, but you don't have to choose the type of `Vec`. If you don't want to choose, you can write `Vec<_>`.

Loading…
Cancel
Save