fn main(){
let mut value: Option<usize> = None;
let mut f = move || {
value = Some(1234);
};
f();
println!("{:?}", value);
}
I don't quite understand why value in this case is still None but I guess this is because of move. Still this seems weird for me, can someone ELI5 me this?
This was easy example, but what I want to do really is to first use filter() on Lines but capture when first match was found (function first returned false) and then using another loop with for_each() to insert new content to that line.
Of course I can use just single for_each here, but is it possible to use both?
Without move I'm getting error that value was borrowed as mutable, and then as non mutable.
To observe the change you have to use a reference.
&mut references are strictly exclusive, so you have to drop f before you can access variables it has exclusive access to.
Alternatively, use &Cell<usize> that can be shared and mutable. Arc<AtomicUsize> if it needs to be thread safe and live for any lifetime (Arc is a kind of reference too).
In this example, you could split the logic of finding the index of the target value and replacing the value (noting that your code replaces the last match). Playground
fn main() {
let test = "lorem\nipsum\ndolor\nipsum";
let replacement = "something";
let lines = test.lines();
let mut buf = String::new();
let index_found = lines
.enumerate()
.filter_map(|(i, line)| if line == "ipsum" { Some(i) } else { None })
.last();
test.lines().enumerate().for_each(|(i, line)| {
if Some(i) == index_found {
buf += replacement;
buf += "\n";
} else {
buf += line;
buf += "\n";
}
});
println!("{}", buf);
}
Is this actually what you want to do? Assuming this compiled, once "ipsum" is found, this would insert the replacement line before all the remaining lines.