I’ve been going through the base code of some Rust library (Carboxyl) and found some weird code. It performs a filter map to a Vector after swapping it with an empty one and reassigning the result to the original identifier.
impl<A: Send + Sync + Clone + 'static> Source<A> {
/// Make the source send an event to all its observers.
pub fn send(&mut self, a: A) {
use std::mem;
let mut new_callbacks = vec!();
mem::swap(&mut new_callbacks, &mut self.callbacks);
self.callbacks = new_callbacks
.into_iter()
.filter_map(|mut callback| {
let result = callback(a.clone());
match result {
Ok(_) => Some(callback),
Err(_) => None,
}
})
.collect();
}
}
What would be the possible benefits of doing so compared to performing filter_map to the original identifier and reassigning the result to itself?
>Solution :
The benefit is that it’s possible.
Because callbacks is part of self which is behind a mutable reference you can’t move out of it with into_iter().
Once drain_filter stabilizes this can be done inplace but until then this is the solution.