43

I'm trying to convert a mutable vector to an immutable vector in Rust. I thought this would work but it doesn't:

let data = &mut vec![];
let x = data;          // I thought x would now be an immutable reference

How can I turn a mutable reference into an immutable binding?

Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
jbrown
  • 6,603
  • 13
  • 61
  • 109
  • This is helpful... for eg. consider the 'partial_shuffle' function in rand crate, it takes in a mutable reference,... that's okay since it has to shuffle in place... But it returns mutable slices too... this thing got me for 2 days, the compiler kept complaining I wasn't able to use the original reference, since it said "can't have a immutable reference since already borrowed as an mutable".... but I couldn't find where I did that, since dataset.partial_shuffle() should be the only one and that mutable borrow must have ended with the function end. Continued... – AdityaG15 Oct 02 '21 at 19:05
  • ... Back to the first line "it takes in a mutable reference,... that's okay since it has to shuffle in place... But it returns mutable slices too", I didn't focus on that, so in such cases, where I don't need the returned random slices to be mutable now, I can just convert them to immutables... Takeaway from this: While reading docs, in rust, focus on the return type : ) – AdityaG15 Oct 02 '21 at 19:07

1 Answers1

50

Dereference then re-reference the value:

fn main() {
    let data = &mut vec![1, 2, 3];
    let x = &*data;
}

For what your code was doing, you should probably read What's the difference in `mut` before a variable name and after the `:`?. Your variable data is already immutable, but it contains a mutable reference. You cannot re-assign data, but you can change the pointed-to value.

How can I turn a mutable reference into an immutable binding?

It already is an immutable binding, as you cannot change what data is.

Community
  • 1
  • 1
Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
  • Hmm this code is in a function that returns `Vec`. If I return `&*data` I get an error `expected struct `std::vec::Vec`, found reference`. If I return `*data* I get an error `cannot move out of borrowed content`. Is that something else about the borrow checker? The way I've resolved this is to return `data.clone()` but I was trying to make it more performant, but I think I the borrow checker might not allow that since I'm creating the vector in the function. Maybe I phrased my question wrong, but how can I get a `Vec` from `data`? – jbrown Dec 28 '16 at 18:50
  • 1
    @jbrown Sounds like you are saying you want `let mut data = vec![1, 2, 3]; return data;`. – Shepmaster Dec 28 '16 at 19:01
  • yes, that's what I was looking for. Thanks. I'll re-read the rust docs about mutability – jbrown Dec 28 '16 at 19:25