关闭时可变借用与不可变借用?

Iod*_*Pit 7 rust

我不知道如何让以下内容发挥作用。我想我需要借用闭包&mut Vec,但我不知道如何表达。这是从一个更大的函数中提取出来的,但显示了相同的错误。

fn main() {
    let mut v = vec![0; 10];

    let next = |i| (i + 1) % v.len();

    v[next(1usize)] = 1;

    v.push(13);

    v[next(2usize)] = 1;    
}
Run Code Online (Sandbox Code Playgroud)

错误:

error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
 --> a.rs:9:5
  |
5 |     let next = |i| {
  |                --- immutable borrow occurs here
6 |         (i + 1) % v.len()
  |                   - first borrow occurs due to use of `v` in closure
...
9 |     v[next(1usize)] = 1;
  |     ^ ---- immutable borrow later used here
  |     |
  |     mutable borrow occurs here

error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

Aco*_*orn 5

如果你真的想用闭包来做到这一点,你将必须通过参数传递向量:

let next = |v: &Vec<_>, i| (i + 1) % v.len();
Run Code Online (Sandbox Code Playgroud)

这使得闭包在每次调用时借用,而不是捕获范围。不过,您仍然需要将借用分开:

let j = next(&v, 1usize);
v[j] = 1;
Run Code Online (Sandbox Code Playgroud)

为了让您的生活更轻松,您可以将所有东西都放在封闭物内:

let next = |v: &mut Vec<_>, i, x| {
    let j = (i + 1) % v.len();
    v[j] = x;
};
Run Code Online (Sandbox Code Playgroud)

这使您可以简单地执行以下操作:

next(&mut v, 1usize, 1);
next(&mut v, 2usize, 2);
// etc.
Run Code Online (Sandbox Code Playgroud)

这种模式对于您编写闭包只是为了避免本地代码重复的情况很有用(我怀疑这就是您在给出注释时询问的原因)。