Mutating the top level captured by the value in the closure of FnMut

I'm trying to create a simple closure program that contains a collection that empties itself gradually:

fn main() {
    let vector = vec![1, 2, 3];

    let mut allow_once = move |i: &i32| -> bool {
        if let Some(index) = vector.position_elem(i) {
            vector.remove(index);
            return true
        }
        false
    };

    for e in &[1, 2, 3, 1, 2, 3] {
        let is_in = if allow_once(e) { "is" } else { "is not" };
        println!("{} {} allowed", e, is_in);
    }
}

      

Seems kosher (to me), but rustc complains (at night):

<anon>:6:13: 6:19 error: cannot borrow captured outer variable in an `FnMut` closure as mutable
<anon>:6             vector.remove(index);
                     ^~~~~~

      

I expect that the problem may be one of the problematic ones. That is, while the implementation never violates the XOR mutation offset principle, perhaps the desurangation is such that it rustc

doesn't understand it.

Thus:

  • Is this a temporary limitation / bug or is it internal?
  • How can I create an environment mutable closure as much as possible?

Note. Capturing by reference is not an option, I want to be able to move the closure.

+3


source to share


1 answer


In fact, the problem can be solved easily. Just add the qualifier mut

to vector

:

fn main() {
    let mut vector = vec![1, 2, 3];

    let mut allow_once = move |i: &i32| -> bool {
        if let Some(index) = vector.position_elem(i) {
            vector.remove(index);
            true
        } else { false }
    };

    for e in &[1, 2, 3, 1, 2, 3] {
        let is_in = if allow_once(e) { "is" } else { "is not" };
        println!("{} {} allowed", e, is_in);
    }
}

      



(working code here )

These are exactly the same mutability rules as always - in order to mutate something, it must have mut

somewhere, either in a variable declaration or in its type ( &mut

).

+6


source







All Articles