rust - How to partition Vec in place in method that doesn't own `self`? -
so, there's struct looks this:
struct foo { alpha: vec<t>, beta: vec<t>, } and method should move values matches condition alpha beta. question is: clean way without owning self?
the vec::partition() method can't used because moving of self.alpha causes cannot move out of dereference of &mut-pointer compile error.
ps: t have file inside doesn't implement clone.
do want drop beta? sort of thing std::mem::replace for, allowing pull out:
use std::mem; impl foo { fn munge(&mut self) { let alpha = mem::replace(&mut self.alpha, vec::new()); let (alpha, beta) = alpha.partition(…); self.alpha = alpha; self.beta = beta; } } note there is new vec created there briefly, doesn’t matter; doesn’t involve allocation , cheap. (the alternative leaving uninitialised memory there , replacing again, forgetting uninitialised memory, unsafe if partition can fail run destructor on uninitialised memory.)
since want shift elements matching predicate, it’s worth looking @ how partition implemented:
pub fn partition<f>(self, mut f: f) -> (vec<t>, vec<t>) f: fnmut(&t) -> bool { let mut lefts = vec::new(); let mut rights = vec::new(); elt in self.into_iter() { if f(&elt) { lefts.push(elt); } else { rights.push(elt); } } (lefts, rights) } knowing how implemented makes implementing doesn’t involve second vector being created rather easy; here’s general idea:
let source = mem::replace(&mut self.alpha, vec::new()); element in source.into_iter() { if f(&element) { /* `f` */ self.alpha.push(element) } else { self.beta.push(element) } } really, mem::replace thing need know these sorts of things; rest becomes easy.
Comments
Post a Comment