Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the idiomatic way to copy from a primitive type reference by value?

Tags:

rust

Consider the following snippet:

fn example(current_items: Vec<usize>, mut all_items: Vec<i32>) {
    for i in current_items.iter() {
        let mut result = all_items.get_mut(i);
    }
}

The compiler is complaining about i being &mut usize instead of usize:

error[E0277]: the trait bound `&usize: std::slice::SliceIndex<[()]>` is not satisfied
 --> src/lib.rs:3:36
  |
3 |         let mut result = all_items.get_mut(i);
  |                                    ^^^^^^^ slice indices are of type `usize` or ranges of `usize`
  |
  = help: the trait `std::slice::SliceIndex<[()]>` is not implemented for `&usize`

I've dug through the docs but the only way I see to satisfy the compiler is i.clone().

I'm definitely missing something obvious here. What's the idiomatic way to copy from primitive type reference by value?

like image 809
Jacob Wang Avatar asked Sep 05 '14 10:09

Jacob Wang


2 Answers

iter() on Vec<T> returns an iterator implementing Iterator<&T>, that is, this iterator will yield references into the vector. This is the most general behavior which allows convenient usage with non-copyable types.

However, primitive types (actually, any types which implement Copy trait) will be copied upon dereference anyway, so you just need this:

for i in current_items.iter() {
    let mut result = all_items.get_mut(*i);
}

Alternatively, you can use reference destructuring pattern:

for &i in current_items.iter() {
    let mut result = all_items.get_mut(i);
}

Now i is usize automatically and you don't need to dereference it manually.

like image 84
Vladimir Matveev Avatar answered Oct 14 '22 12:10

Vladimir Matveev


What's the idiomatic way to copy from primitive type reference by value?

You need to use * to dereference a reference.

let my_usize: usize = 5;
let ref_to_my_usize: &usize = &my_usize;
let copy_of_my_usize: usize = *ref_to_my_usize;

You can also dereference directly in your loop:

for &x in myvec.iter() {
//  ^-- note the &
}
like image 11
Levans Avatar answered Oct 14 '22 13:10

Levans