diff --git a/src/doc/guide.md b/src/doc/guide.md index 5357a0fcafa14..db97fc0644416 100644 --- a/src/doc/guide.md +++ b/src/doc/guide.md @@ -1496,87 +1496,102 @@ low-level details matter, they really matter. Just remember that `String`s allocate memory and control their data, while `&str`s are a reference to another string, and you'll be all set. -# Vectors +# Arrays, Vectors, and Slices -Like many programming languages, Rust has a list type for when you want a list -of things. But similar to strings, Rust has different types to represent this -idea: `Vec` (a 'vector'), `[T, .. N]` (an 'array'), and `&[T]` (a 'slice'). -Whew! +Like many programming languages, Rust has list types to represent a sequence of +things. The most basic is the **array**, a fixed-size list of elements of the +same type. By default, arrays are immutable. -Vectors are similar to `String`s: they have a dynamic length, and they -allocate enough memory to fit. You can create a vector with the `vec!` macro: +```{rust} +let a = [1i, 2i, 3i]; +let mut m = [1i, 2i, 3i]; +``` + +You can create an array with a given number of elements, all initialized to the +same value, with `[val, ..N]` syntax. The compiler ensures that arrays are +always initialized. ```{rust} -let nums = vec![1i, 2i, 3i]; +let a = [0i, ..20]; // Shorthand for array of 20 elements all initialized to 0 ``` -Notice that unlike the `println!` macro we've used in the past, we use square -brackets (`[]`) with `vec!`. Rust allows you to use either in either situation, -this is just convention. +Arrays have type `[T,..N]`. We'll talk about this `T` notation later, when we +cover generics. -You can create an array with just square brackets: +You can get the number of elements in an array `a` with `a.len()`, and use +`a.iter()` to iterate over them with a for loop. This code will print each +number in order: ```{rust} -let nums = [1i, 2i, 3i]; -let nums = [1i, ..20]; // Shorthand for an array of 20 elements all initialized to 1 +let a = [1i, 2, 3]; // Only the first item needs a type suffix + +println!("a has {} elements", a.len()); +for e in a.iter() { + println!("{}", e); +} ``` -So what's the difference? An array has a fixed size, so you can't add or -subtract elements: +You can access a particular element of an array with **subscript notation**: -```{rust,ignore} -let mut nums = vec![1i, 2i, 3i]; -nums.push(4i); // works +```{rust} +let names = ["Graydon", "Brian", "Niko"]; -let mut nums = [1i, 2i, 3i]; -nums.push(4i); // error: type `[int, .. 3]` does not implement any method - // in scope named `push` +println!("The second name is: {}", names[1]); ``` -The `push()` method lets you append a value to the end of the vector. But -since arrays have fixed sizes, adding an element doesn't make any sense. -You can see how it has the exact type in the error message: `[int, .. 3]`. -An array of `int`s, with length 3. +Subscripts start at zero, like in most programming languages, so the first name +is `names[0]` and the second name is `names[1]`. The above example prints +`The second name is: Brian`. If you try to use a subscript that is not in the +array, you will get an error: array access is bounds-checked at run-time. Such +errant access is the source of many bugs in other systems programming +languages. -Similar to `&str`, a slice is a reference to another array. We can get a -slice from a vector by using the `as_slice()` method: +A **vector** is a dynamic or "growable" array, implemented as the standard +library type [`Vec`](std/vec/) (we'll talk about what the `` means +later). Vectors are to arrays what `String` is to `&str`. You can create them +with the `vec!` macro: ```{rust} -let vec = vec![1i, 2i, 3i]; -let slice = vec.as_slice(); +let v = vec![1i, 2, 3]; ``` -All three types implement an `iter()` method, which returns an iterator. We'll -talk more about the details of iterators later, but for now, the `iter()` method -allows you to write a `for` loop that prints out the contents of a vector, array, -or slice: +(Notice that unlike the `println!` macro we've used in the past, we use square +brackets `[]` with `vec!`. Rust allows you to use either in either situation, +this is just convention.) -```{rust} -let vec = vec![1i, 2i, 3i]; +You can get the length of, iterate over, and subscript vectors just like +arrays. In addition, (mutable) vectors can grow automatically: -for i in vec.iter() { - println!("{}", i); -} +```{rust} +let mut nums = vec![1i, 2, 3]; +nums.push(4); +println!("The length of nums is now {}", nums.len()); // Prints 4 ``` -This code will print each number in order, on its own line. +Vectors have many more useful methods. -You can access a particular element of a vector, array, or slice by using -**subscript notation**: +A **slice** is a reference to (or "view" into) an array. They are useful for +allowing safe, efficient access to a portion of an array without copying. For +example, you might want to reference just one line of a file read into memory. +By nature, a slice is not created directly, but from an existing variable. +Slices have a length, can be mutable or not, and in many ways behave like +arrays: ```{rust} -let names = ["Graydon", "Brian", "Niko"]; +let a = [0i, 1, 2, 3, 4]; +let middle = a.slice(1, 4); // A slice of a: just the elements [1,2,3] -println!("The second name is: {}", names[1]); +for e in middle.iter() { + println!("{}", e); // Prints 1, 2, 3 +} ``` -These subscripts start at zero, like in most programming languages, so the -first name is `names[0]` and the second name is `names[1]`. The above example -prints `The second name is: Brian`. +You can also take a slice of a vector, `String`, or `&str`, because they are +backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover +generics. -There's a whole lot more to vectors, but that's enough to get started. We have -now learned all of the most basic Rust concepts. We're ready to start building -our guessing game, but we need to know how to do one last thing first: get +We have now learned all of the most basic Rust concepts. We're ready to start +building our guessing game, we just need to know one last thing: how to get input from the keyboard. You can't have a guessing game without the ability to guess!