How can I build a `Vec<i32>` from an `Iterator<Item=&i32>`?

4.8k Views Asked by At

I encountered an error when trying to use a function get_even_numbers() to borrow a vec v by passing it in by reference &v instead of by value v.

fn get_even_numbers(v: &Vec<i32>) -> Vec<i32> {
    v.iter().filter(|x| x % 2 == 0).collect()
}

fn main() {
    let v: Vec<i32> = (0..10).collect();
    let even: Vec<i32> = get_even_numbers(&v);
    println!("Even numbers: {:?}", even);
}
error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `&i32`
 --> src/main.rs:2:37
  |
2 |     v.iter().filter(|x| x % 2 == 0).collect()
  |                                     ^^^^^^^ value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=&i32>`
  |
  = help: the trait `FromIterator<&i32>` is not implemented for `Vec<i32>`
  = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
note: required by a bound in `collect`

Why does the above give an error, but passing it in by value does not, as shown below?

fn get_even_numbers(v: Vec<i32>) -> Vec<i32> {
    v.into_iter().filter(|x| x % 2 == 0).collect()
}

fn main() {
    let v: Vec<i32> = (0..10).collect();
    let even: Vec<i32> = get_even_numbers(v);
    println!("Even numbers: {:?}", even);
}
Even numbers: [0, 2, 4, 6, 8]

I used .iter() inside the function when passing in by reference and .into_iter() when passing in by value, not sure if these are the correct functions to use.

1

There are 1 best solutions below

1
On

Use v.iter().filter(|x| x % 2 == 0).cloned().collect(). That will (trivially) clone each of the &i32 references into actual i32 values.