Reputation: 11
In rust, when letting rust's iter.filter
closure parameter capture a local variable, and I mutate that local variable in that closure, I am unable to use it at all until i finish using the iterator. It is obvious in my Minimal Reproducible Example:
fn main() {
let my_str = "12345";
let mut num_i_need = 1;
let iterator = my_str
.chars()
.filter(|code_char| {
// ... logic to see if `code_char` should be filtered..
num_i_need += 1;
true
})
.peekable();
dbg!(num_i_need); // <- problem
// Now when we loop:
for my_char in iterator {
dbg!(num_i_need); // <- problem
dbg!(&num_i_need); // <- problem
}
dbg!(num_i_need); // <- fine
}
I hope to be able to use the variable num_i_need
outside of .filter
's closure (I don't intend to mutate it outside the closure) and without needing to use a Cell
I had to use a Cell
to get the example to work:
use std::cell::Cell;
fn main() {
let my_str = "12345";
let num_i_need = Cell::new(1);
let iterator = my_str
.chars()
.filter(|code_char| {
// ... logic to see if `code_char` should be filtered..
num_i_need.set(num_i_need.get() + 1);
true
})
.peekable();
dbg!(&num_i_need); // fine here
// Now when we loop:
for my_char in iterator {
dbg!(&num_i_need); // <- NO problem, is fine
}
dbg!(num_i_need); // also fine
}
However in my actual codebase, I have 3 variables rather than 1 here, so I find this to be kind of undesirable and I am wondering if there is a more idiomatic way to achieve this without a Cell
Upvotes: 1
Views: 379
Reputation: 11
I ended up converting my .fillter
to a .scan
so that it can hold state, and it just passes that state on each .next()
on the iterator, to keep filtering I used a .filter
after my .scan
(although that is not shown in the simple example here)
fn main() {
let my_str = "12345";
let iterator = my_str
.chars()
.scan(1, |num_i_need, code_char| {
*num_i_need += 1;
Some((num_i_need.clone(), code_char))
}) // you would have a `.filter` here to filter stuff out instead
.peekable();
// Now when we loop:
for (num_i_need, code_char) in iterator {
dbg!(num_i_need); // <- NO problem, is fine (Without Cell!!)
dbg!(code_char); // (also fine)
}
}
Upvotes: 0