1

I'm confused as to when to use references. I have a vector and I'd like to iterate through the elements inside it.

let v = vec![1, 2, 3, 4, 5];

I can do this using a for loop in two ways:

Method 1

for element in &v {
    println!("{}", element);
}

Method 2

for element in v {
    println!("{}", element);
}

In method 1, I use a reference to access the contents of the vector v. Both examples compile and give the desired output. Which method to use and why?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Vineet Reddy
  • 41
  • 1
  • 8
  • 1
    "Method 2" consumes the vector and yields the actual elements, while method 1 only borrows the vector, yielding references to the elements. Which method to use depends on what you want or need with respect to that. – Masklinn Jun 30 '20 at 11:02
  • Thanks! That makes sense. I stick to references as vector types do not have the copy trait? – Vineet Reddy Jun 30 '20 at 11:04
  • @VineetReddy, it depends on what you are doing. References are more common, but sometimes you have e.g. `Box`es with some large structures and want to move them somewhere else to avoid reallocating and then you will use values. – Jan Hudec Jun 30 '20 at 11:23
  • @VineetReddy You shouldn't limit yourself like that, basically first one lets you borrow the elements of the `Vec`, second one lets you have the ownership of the elements by destructing the `Vec`. The rest depends on the answer of this question: Do i need an ownership or do i need to borrow? For more information you may want to check difference between `Vec::iter()` vs `Vec::into_iter()`. – Ömer Erden Jun 30 '20 at 11:31
  • See also https://stackoverflow.com/questions/62410265/is-there-any-difference-in-these-approaches-to-iterate-through-a-vector and the duplicates linked there. – Jmb Jun 30 '20 at 11:45

1 Answers1

-1

The below piece of code consumes v. Although both methods in your code do the same thing, however after method 2, you won't be able to access v. See here Playground link

for element in v {
    println!("{}", element);
}

Now, most of the times, unless you want to consume the vector, we use references instead of values. If you are given a slice or vector reference like say input to an function, you can only use method 1.

fn do_something(v: &[i32]) {
    // body of the function
}

argument type could also be &Vec[i32]. However, this approach has drawbacks.

apatniv
  • 1,771
  • 10
  • 13
  • Bad example. [You should not have `&Vec` parameters](https://stackoverflow.com/questions/40006219/why-is-it-discouraged-to-accept-a-reference-to-a-string-string-vec-vec-o). – mcarton Jun 30 '20 at 10:46
  • IMO, the user can use the slice but I guess that doesn't convey the point. Ok let me add update it. – apatniv Jun 30 '20 at 10:51
  • So the idea is that, unless I would like values to be consumed, I stick to references as vector types do not have the copy trait? – Vineet Reddy Jun 30 '20 at 11:02
  • Vectors can only be cloned because implicit copy like what c++ does is expensive by default. – apatniv Jun 30 '20 at 11:08
  • If this is the case, then how come, access the vector through an index -- say v[0] does not move the value? – Vineet Reddy Jun 30 '20 at 11:19
  • Compiler will prevent it. so, you may need to write it as &v[0] instead v[0]. – apatniv Jun 30 '20 at 11:25