2017-12-24 16 views

답변

2

가장 가까운 추상화는 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) 
})) 
+0

감사를 완벽! –