Explanation about an example of borrowing



I’m trying to do the rustlings exercises to get familiar with rust, and I’m having trouble with the second execrise of move semantic.

Here is my first solution. It’s working but I don’t understand why:

// Make me compile without changing line 9! Scroll down for hints :)

pub fn main() {
    let vec0: Vec<i32> = Vec::new();
    // Just borrow vec0 instead of taking ownership of it
    let mut vec1 = fill_vec(&vec0);

    // This line cannot be changed
    println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);


    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);


# Change argument type to &Vec<i32>
fn fill_vec(vec: &Vec<i32>) -> Vec<i32> {

    let mut new_vec: Vec<i32> = Vec::new();
    // I thought I had to dereference vec, since its type is &Vec<i32>,
    // which reads as "reference to a Vec of i32" (if I'm not mistaken),
    // and I cannot iterate over a reference.
    // for i in *vec { 
    //     new_vec.push(i);
    // }
    // But it does not work. and I don't understand why.
    // Error is "cannot move out of borrowed content"
    // This works though, but I just tried it randomly,
    // so not sure why. How come I have to dereference `i`?
    // Very confused here...
    for i in vec { 

Also, is that the correct way to copy a vector? I looked for a copy() function but did not find that.

Hope this kind of question is approriate on the forum since questions seems more general.



first things first, here’s another working solution (http://is.gd/Jpn8iP)

pub fn main() {
    let vec0 = Vec::new();

    let mut vec1 = fill_vec(&vec0);

    // Do not change the following line!
    println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);


    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);


fn fill_vec(vec: &Vec<i32>) -> Vec<i32> {
    let mut vec = vec.to_vec(); // this copies the vector for if T is `Clone`



And a few explanations:


Generally, when you want to manually copy something, you call clone(). Copy is when it happens automatically without your help.

for loops are unusual.

let vec0 = vec![1, 2, 3];
// This will work perfectly because the `for` loop calls `into_iter()`
// on the vec converting it into something iterable. It is moved
// in the process so `vec` is no longer accessible.
for v in vec0 { println!("{}", v); }

let vec1 = &vec![1, 2, 3];
// This is a bit different. This calls `into_iter()` on the borrowed vector
// which does something depending on the implementation but at the
// most *cannot* modify or move the borrow. `into_iter()` on a borrowed vector
// calls `iter()` on the vec which yields borrows to each element.
for v in vec1 { println!("{}", *v); }

let vec2 = &vec![1, 2, 3];
// A `for` loop always calls `into_iter()` but sometimes the fact that
// you're working with a borrowed value may not be obvious. To make
// this more clear, you dereference first and then borrow.
for v in &*vec2 { println!("{}", *v); }

// Since a proper implementation of `into_iter()` should defer to `iter`
// and `iter_mut` in the appropriate cases, association of `iter` with `&`
// and `iter_mut` with `&mut` seems appropriate.
let mut vec3 = vec![1, 2, 3];
for v in &mut vec3 { println!("mutating {} in vec3", v); *v += 1; }
for v in &vec3 { println!("borrowing {} from vec3", v); }
for v in vec3 { println!("consumed vec3 and looking at {}", v); }