可变ref在闭包内部变为不可变

时间:2018-08-30 19:31:32

标签: rust

我具有生成随机向量的功能。

pub fn random_vec(r: &mut rng::Rng, n: u32) -> Vec<Flo> {
    (0..n).map(|_| r.next_normal()).collect()
}

我用它来生成一个包含3个随机向量的向量。

let xs: Vec<Vec<Flo>> =
    (0..3).map(|_| random_vec(&mut r, n)).collect();

这很好。现在,我尝试将这一行提取到函数中。

fn random_vecs(r: &mut rng::Rng, n: u32) -> Vec<Vec<Flo>> {
    (0..3).map(|_| random_vec(&mut r, n)).collect()
}

此操作失败,并显示以下消息:“无法将闭包分配给不可变参数`r`”。为什么Rust希望r不可变?

1 个答案:

答案 0 :(得分:4)

从技术上讲,由于r的形式参数random_vecs不可更改,并且您体内的&mut r试图构造对其的可变引用。

这是一个简化的示例,其中包含您正在做的事情的基本内容:

fn modify0(r: &mut usize) {
    *r += 1;
}

fn modify1(r: &mut usize) {
    modify0(&mut r);
}

fn main() {
    let mut a = 1;
    modify1(&mut a);

    println!("Hello, {:?}!", a);
}

错误消息是

error[E0596]: cannot borrow immutable argument `r` as mutable
 --> src/main.rs:6:18
  |
6 |     modify0(&mut r);
  |                  ^ cannot borrow mutably
help: consider removing the `&mut`, as it is an immutable binding to a mutable reference

要修复它,您可以使其可变(尽管它在这里工作,但这不是个好主意):

fn modify1(mut r: &mut usize) {
    modify0(&mut r);
}

最好遵循错误消息中的建议,并删除多余的&mut

fn modify1(r: &mut usize) {
    modify0(r);
}