Home > Mobile >  pass ownership in a nested loop
pass ownership in a nested loop

Time:01-14

I am trying to implement a sieve of eratosthenes, this finds all pirmes below n by creating an array, iterating through that array and whenever a prime is found marking off all multiples of that prime as non-prime.

My code for the marking step is:

for (index, val) in is_prime[3..marking_lim].iter_mut().step_by(2).enumerate() {     // borrow of is_prime
    if *val == true {
       primes_found.push(index as i32);           // add the prime to the list
       n_found  = 1;                               // counter for primes found, cannot be exceeded in this step
       for val_2 in is_prime[index..(up_to_nth as usize)].iter_mut().step_by(index) {   // second borrow of is_prime
            *val_2 = false;
        }
    }
}

However, this doesn't work as the inner loop takes a mutable borrow of is_prime while it's still borrowed by the outer loop. Therefore, I need to somehow transfer ownership of the borrow to the inner loop so it can mark of the multiples. How can I do that?

CodePudding user response:

It's not possible to do exactly what you're asking. The easiest solution is to avoid borrowing is_prime in the outer loop:

for (index, index_2) in (3..marking_lim).step_by(2).enumerate() {
    if is_prime[index_2] {
        // ...

A fancier solution is to use std::cell::Cell, which lets you mutate the array items through a non-mut reference:

use std::cell::Cell;

let is_prime = Cell::from_mut(&mut is_prime[..]).as_slice_of_cells();

for (index, val) in is_prime[3..marking_lim].iter().step_by(2).enumerate() {
    if val.get() {
        primes_found.push(index as i32);
        n_found  = 1;
        for val_2 in is_prime[index..(up_to_nth as usize)].iter().step_by(index) {
            val_2.set(false);
        }
    }
}
  • Related