Although I understand Rust's approach to memory safety, the ownership concepts, and have no problem with references in general, I'm struggling to figure out how Rust wants me to solve a seemingly trivial problem.
This code is a minimal example.
A struct:
pub struct S {
value: Option<i8>,
}
with a getter that computes a value the first time, then returns the stored value:
use rand::Rng;
impl S {
fn get_value(&mut self) -> i8 {
if let Some(v) = self.value {
return v;
}
let v = rand::thread_rng().gen::<i8>();
self.value = Some(v);
v
}
}
Of course, get_value() needs a mutable reference &mut self, because it modifies self.
This mutability is the source of my struggling when I want to sort a vector of references to S, by the result of get_value(). Because I want to sort by get_value(), the comparison function used by sort_by will need mutable references.
My first attempt:
fn main() {
let mut a = S {value: None};
let mut b = S {value: None};
let mut c = S {value: None};
let mut v = vec![&mut a, &mut b, &mut c];
v.sort_by( |a, b| a.get_value().cmp(&b.get_value()) );
}
Throws:
error[E0596]: cannot borrow `**a` as mutable, as it is behind a `&` reference
--> src/main.rs:27:20
|
27 | v.sort_by( |a, b| a.get_v().cmp(&b.get_v()) );
| - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| |
| help: consider changing this to be a mutable reference: `&mut &mut S`
My initial thought was that having a vector of mutable references in the first place would allow the comparison function to use mutable references. My getter function however borrows a mutable reference to a mutable reference, that's why the error says cannot borrow '**a'.
The help suggests to change |a,b| so that they are &mut &mut S references.
Is &mut &mut the same as &&mut?
Does it mean I should change it into |mut a:&&mut S, mut b:&&mut S|?