When passing two elements from the same vector to a function, the borrow checker will not allow one of the elements to be mutable.
struct Point {
x: i32,
y: i32,
}
fn main() {
let mut vec: Vec<Point> = Vec::new();
foo(&mut vec[0], &vec[1]);
}
fn foo(pnt_1: &mut Point, pnt_2: &Point) {
}
error: cannot borrow
vec
as immutable because it is also borrowed as mutable
vec
is never borrowed by foo
though, vec[0]
is borrowed and vec[0]
is a Point
.
How can I pass multiple elements from the same collection into a function with one or more of the elements being mutable?
How can I pass multiple elements from the same collection into a function with one or more of the elements being mutable?
The short answer is that you cannot, at least not without support from the collection itself.
Rust disallows mutable aliases - multiple names for the same thing, one of which allows mutation.
It would be far too complicated (with the current state of programming languages) to verify that (&mut vec[0], &vec[1])
does not introduce aliasing but (&mut vec[0], &vec[0])
does. Adding to the complexity is the fact that the []
operator can be overloaded, which allows creating a type such that foo[0]
and foo[1]
actually point at the same thing.
So, how can a collection help out? Each collection will have (or not have) a specific way of subdivision in an aliasing-safe manner.
There can be methods like slice::split_at_mut
which verify that that two halves cannot overlap and thus no aliasing can occur.
Unfortunately, there's no HashMap::get_two_things(&a, &b)
that I'm aware of. It would be pretty niche, but that doesn't mean it couldn't exist.
vec
is never borrowed byfoo
though
It most certainly is. When you index a Vec
, you are getting a reference to some chunk of memory inside the Vec
. If the Vec
were to change underneath you, such as when someone adds or removes a value, then the underlying memory may need to be reallocated, invalidating the reference. This is a prime example of why mutable aliasing is a bad thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With