问题
I'm trying to nail down ownership rules. I want to:
- start with a mutable reference to a slice
- make some edits to its contents
- reduce the slice reference to a reference of a sub-slice and repeat
Below is my attempt:
pub fn example() {
// Make a mutable slice
let mut v = [0, 1, 2, 3];
// Make a mutable reference to said slice
let mut v_ref = &mut v[..];
while v_ref.len() > 1 {
// Involves some edits -> need mut
v_ref.swap(0, v_ref.len() - 1);
// Try to reduce slice to sub-slice (some simplification here)
// Errors!
let (v_l, v_h) = v.split_at_mut(v.len() / 2);
v_ref = v_l;
}
}
However I'm getting the errors:
error[E0502]: cannot borrow `*v_ref` as immutable because it is also borrowed as mutable
--> src/lib.rs:11:23
|
11 | v_ref.swap(0, v_ref.len() - 1);
| ----- ^^^^^ - mutable borrow ends here
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
error[E0499]: cannot borrow `v` as mutable more than once at a time
--> src/lib.rs:15:26
|
7 | let mut v_ref = &mut v[..];
| - first mutable borrow occurs here
...
15 | let (v_l, v_h) = v.split_at_mut(v.len() / 2);
| ^ second mutable borrow occurs here
...
18 | }
| - first borrow ends here
error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
--> src/lib.rs:15:41
|
7 | let mut v_ref = &mut v[..];
| - mutable borrow occurs here
...
15 | let (v_l, v_h) = v.split_at_mut(v.len() / 2);
| ^ immutable borrow occurs here
...
18 | }
| - mutable borrow ends here
I understand that you can't have multiple references to an object in the same scope as a single mutable reference.
There should be a safe way to reduce a slice's range, as you're only reducing the scope of a current mutable reference. What's the best way to do that?
回答1:
Problem 1: Using the same variable mutably and immutably
As Peter Hall points out, the code attempts to reference the variable v
while there's a concurrent mutable reference to it, even though you don't care about v_ref
anymore. A MCVE:
pub fn example() {
let mut v = 0;
let mut v_ref = &mut v;
println!("{}", v)
}
See also:
- What are non-lexical lifetimes?
Problem 2: Using the same variable mutably and immutably
Then the code attempts to overlap mutable and mutable borrows in a single function call. A MCVE:
pub fn example() {
let mut v = [0, 1, 2, 3];
v.split_at_mut(v.len());
}
See also:
- Cannot borrow as immutable because it is also borrowed as mutable in function arguments
Problem 3: Using the same variable mutably and mutably
Then the code has overlapping mutable borrows of v
in the loop.
See also:
- Cannot obtain a mutable reference when iterating a recursive structure: cannot borrow as mutable more than once at a time
All together:
pub fn example() {
let mut v = [0, 1, 2, 3];
let mut v_ref = &mut v[..];
while v_ref.len() > 1 {
let len = v_ref.len();
v_ref.swap(0, len - 1);
let (v_l, _) = { v_ref }.split_at_mut(len / 2);
v_ref = v_l;
}
}
来源:https://stackoverflow.com/questions/52026575/errors-in-overwriting-slice-reference-with-sub-slice-reference