Hello!
First of all, sorry about my English. I've been struggling with a compilation problem related to using a closure inside a while loop. This is a simplification of my real code to show the problem.
fn test(rng: &mut StdRng) {
let num_of_indexes = 20;
let mut some_value: f32 = 0.0;
let normal = Normal::new(0.0, 0.3);
// Initialize vector of indexes and shuffles it
let mut indexes: Vec<usize> = (0..num_of_indexes).collect();
indexes.shuffle(rng);
// Closure that fills and shuffle indexes
let mut fill_and_shuffle = || {
indexes = (0..num_of_indexes).collect();
indexes.shuffle(rng);
};
// If i call the closure outside the loop it works perfectly
fill_and_shuffle();
fill_and_shuffle();
for _ in 0..3 {
// In real code I have to do this multiple times
if indexes.is_empty() {
indexes = (0..num_of_indexes).collect();
indexes.shuffle(rng);
}
// If I uncomment this, it brokes
// fill_and_shuffle();
let index = indexes.pop().expect("El vector está vacio");
// Mutation
some_value += normal.sample(rng) as f32;
}
}
It works fine if I use it outside the loop, but if I call it inside the loop, it doesn't compile and return this error message:
error[E0502]: cannot borrow indexes
as immutable because it is also borrowed as mutable
--> src/main.rs:928:12
|
917 | let mut fill_and_shuffle = || {
| -- mutable borrow occurs here
918 | indexes = (0..num_of_indexes).collect();
| ------- first borrow occurs due to use of indexes
in closure
...
928 | if indexes.is_empty() {
| ^^^^^^^ immutable borrow occurs here
...
934 | fill_and_shuffle();
| ---------------- mutable borrow used here, in later iteration of loop
error[E0506]: cannot assign to indexes
because it is borrowed
--> src/main.rs:929:13
|
917 | let mut fill_and_shuffle = || {
| -- borrow of indexes
occurs here
918 | indexes = (0..num_of_indexes).collect();
| ------- borrow occurs due to use in closure
...
929 | indexes = (0..num_of_indexes).collect();
| ^^^^^^^ assignment to borrowed indexes
occurs here
...
934 | fill_and_shuffle();
| ---------------- borrow used here, in later iteration of loop
error[E0499]: cannot borrow indexes
as mutable more than once at a time
--> src/main.rs:930:13
|
917 | let mut fill_and_shuffle = || {
| -- first mutable borrow occurs here
918 | indexes = (0..num_of_indexes).collect();
| ------- first borrow occurs due to use of indexes
in closure
...
930 | indexes.shuffle(rng);
| ^^^^^^^ second mutable borrow occurs here
...
934 | fill_and_shuffle();
| ---------------- first borrow used here, in later iteration of loop
error[E0501]: cannot borrow *rng
as mutable because previous closure requires unique access
--> src/main.rs:930:29
|
917 | let mut fill_and_shuffle = || {
| -- closure construction occurs here
918 | indexes = (0..num_of_indexes).collect();
919 | indexes.shuffle(rng);
| --- first borrow occurs due to use of rng
in closure
...
930 | indexes.shuffle(rng);
| ^^^ second borrow occurs here
...
934 | fill_and_shuffle();
| ---------------- first borrow used here, in later iteration of loop
error[E0499]: cannot borrow indexes
as mutable more than once at a time
--> src/main.rs:936:21
|
917 | let mut fill_and_shuffle = || {
| -- first mutable borrow occurs here
918 | indexes = (0..num_of_indexes).collect();
| ------- first borrow occurs due to use of indexes
in closure
...
934 | fill_and_shuffle();
| ---------------- first borrow used here, in later iteration of loop
935 |
936 | let index = indexes.pop().expect("El vector está vacio");
| ^^^^^^^ second mutable borrow occurs here
error[E0501]: cannot borrow *rng
as mutable because previous closure requires unique access
--> src/main.rs:939:37
|
917 | let mut fill_and_shuffle = || {
| -- closure construction occurs here
918 | indexes = (0..num_of_indexes).collect();
919 | indexes.shuffle(rng);
| --- first borrow occurs due to use of rng
in closure
...
934 | fill_and_shuffle();
| ---------------- first borrow used here, in later iteration of loop
...
939 | some_value += normal.sample(rng) as f32;
| ^^^ second borrow occurs here
error: aborting due to 6 previous errors
I've read the doc and I've done some research, but I didn't find anything that explains me this(I'm new to Rust). Maybe Rust borrows variables when it enters a loop or something like that, I don't know.
Thanks in advance!