What is the operation when vector is indexed (without &)

Viewed 165

As per rust book (vectors section - Ch-8.1)

let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0]; // <-- This is an immutable borrow
v.push(6); // Which is why push() operation is not allowed (since this is a mutable borrow)
println!("The first element is: {}", first);

Because &v[0] is an immutable borrow, v.push(100) operation should not work. Which makes sense.

However, this works:

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

When & is removed from v[0], push() operation works fine.

Question(s):

  1. If adding & creates a reference (and does not move ownership), does this mean after removing &, the ownership of v[0] is moved to variable first? If so, I am able to access v[0] afterwards. Why is that?
  2. If (1) is not the case, is this a Copy operation? i.e value stored at memory location v[0] is copied to variable first?
  3. If not (2), what exactly is happening here?
1 Answers

Yes, this is a copy, since without & it's moving and moving i32 is copying it since it implements the Copy trait (moreover, you cannot move out of an index, so this must be a copy).

Edit: As suggested by @prog-fh in the comment, if you use a non-Copy type the compiler will tell you that:

struct NoCopy;
let mut v = vec![NoCopy];
let _first = v[0];
error[E0507]: cannot move out of index of `Vec<NoCopy>`
 --> src/main.rs:4:18
  |
4 |     let _first = v[0];
  |                  ^^^^
  |                  |
  |                  move occurs because value has type `NoCopy`, which does not implement the `Copy` trait
  |                  help: consider borrowing here: `&v[0]`

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

Playground.

Related