Slices

Let's go back to the memory layout of a Vec:

let mut numbers = Vec::with_capacity(3);
numbers.push(1);
numbers.push(2);
      +---------+--------+----------+
Stack | pointer | length | capacity | 
      |  |      |   2    |    3     |
      +--|------+--------+----------+
         |
         |
         v
       +---+---+---+
Heap:  | 1 | 2 | ? |
       +---+---+---+

We already remarked how String is just a Vec<u8> in disguise.
The similarity should prompt you to ask: "What's the equivalent of &str for Vec?"

&[T]

[T] is a slice of a contiguous sequence of elements of type T.
It's most commonly used in its borrowed form, &[T].

There are various ways to create a slice reference from a Vec:

let numbers = vec![1, 2, 3];
// Via index syntax
let slice: &[i32] = &numbers[..];
// Via a method
let slice: &[i32] = numbers.as_slice();
// Or for a subset of the elements
let slice: &[i32] = &numbers[1..];

Vec implements the Deref trait using [T] as the target type, so you can use slice methods on a Vec directly thanks to deref coercion:

let numbers = vec![1, 2, 3];
// Surprise, surprise: `iter` is not a method on `Vec`!
// It's a method on `&[T]`, but you can call it on a `Vec` 
// thanks to deref coercion.
let sum: i32 = numbers.iter().sum();

Memory layout

A &[T] is a fat pointer, just like &str.
It consists of a pointer to the first element of the slice and the length of the slice.

If you have a Vec with three elements:

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

and then create a slice reference:

let slice: &[i32] = &numbers[1..];

you'll get this memory layout:

                  numbers                          slice
      +---------+--------+----------+      +---------+--------+
Stack | pointer | length | capacity |      | pointer | length |
      |    |    |   3    |    4     |      |    |    |   2    |
      +----|----+--------+----------+      +----|----+--------+
           |                                    |  
           |                                    |
           v                                    | 
         +---+---+---+---+                      |
Heap:    | 1 | 2 | 3 | ? |                      |
         +---+---+---+---+                      |
               ^                                |
               |                                |
               +--------------------------------+

&Vec<T> vs &[T]

When you need to pass an immutable reference to a Vec to a function, prefer &[T] over &Vec<T>.
This allows the function to accept any kind of slice, not necessarily one backed by a Vec.

For example, you can then pass a subset of the elements in a Vec. But it goes further than that—you could also pass a slice of an array:

let array = [1, 2, 3];
let slice: &[i32] = &array;

Array slices and Vec slices are the same type: they're fat pointers to a contiguous sequence of elements. In the case of arrays, the pointer points to the stack rather than the heap, but that doesn't matter when it comes to using the slice.