가장 가까운 추상화는 Iterator::scan
입니다. 내부적으로 변경 가능한 상태 (결과 반복자에 대해 다른 값을 생성 할 수 있음)를 가지며 초기에 중단 될 수 있기 때문에 좀 더 강력합니다.
당신은 반복자 확장 특성을 구축하기 위해이처럼 사용할 수 있습니다
Playground
pub trait FoldListExt: Iterator {
fn fold_list<'a, St: 'a, F: 'a>(self, initial_state: St, f: F) -> Box<Iterator<Item = St> + 'a>
where
St: Clone,
F: FnMut(St, Self::Item) -> St,
Self: 'a;
}
impl<I: Iterator> FoldListExt for I {
fn fold_list<'a, St: 'a, F: 'a>(
self,
initial_state: St,
mut f: F,
) -> Box<Iterator<Item = St> + 'a>
where
St: Clone,
F: FnMut(St, Self::Item) -> St,
Self: 'a,
{
Box::new(self.scan(Some(initial_state), move |state, item| {
let old_state = state.take().unwrap();
*state = Some(f(old_state.clone(), item));
Some(old_state)
}))
}
}
pub fn main() {
println!(
"{:?}",
(0..16)
.into_iter()
.fold_list(0, |a, b| a + b)
.collect::<Vec<_>>()
);
}
나는 다른
clone()
호출을 방지하기 위해 내부 가변 상태에 대한
Option<St>
을 사용했다.
대신이를 사용할 수 있습니다
Box::new(self.scan(initial_state, move |state, item| {
let old_state = state.clone();
*state = f(old_state.clone(), item);
Some(old_state)
}))
감사를 완벽! –