Изменяемый реф становится неизменным внутри закрытия - PullRequest
0 голосов
/ 30 августа 2018

У меня есть эта функция для генерации случайного вектора.

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 голосов
/ 31 августа 2018

Технически, потому что формальный аргумент 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...