# Iterator 트레이트와 관련 메서드(next, fold 등)

Rust의 이터레이터는 어떤 종류의 자료 구조, 스트림, 혹은 다른 형태의 반복 가능한 데이터에 대해 순차적으로 접근하기 위한 핵심 추상화로서, 가장 기본적으로는 Iterator 트레이트를 통해 정의된다. 이 트레이트는 단 하나의 필수 메서드 next를 요구하며, 이 메서드를 통해 반복 과정에서 각 아이템을 꺼내온다. 그 외에도 fold를 비롯한 각종 메서드들이 디폴트 구현으로 제공되어, 여러 종류의 누적 작업과 변환 작업을 간단하고 안전하게 구현할 수 있게 돕는다.

Iterator 트레이트는 다음과 같이 정의된다 (단순화된 형태).

```rust
pub trait Iterator {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;

    // 디폴트 메서드들(예: fold, collect, map 등)...
}
```

next 메서드는 반복자의 현재 상태를 바탕으로, 다음 요소를 꺼내 반환한다. 요소가 더 이상 없으면 None을 반환한다. 일반적으로 next는 \&mut self를 취하므로, 같은 이터레이터 값에 대해 next를 계속 호출하면 그 상태가 계속 변경되어 간다고 볼 수 있다. 예시는 다음과 같다.

```rust
let numbers = vec![10, 20, 30];
let mut iter = numbers.iter();

assert_eq!(iter.next(), Some(&10));
assert_eq!(iter.next(), Some(&20));
assert_eq!(iter.next(), Some(&30));
assert_eq!(iter.next(), None);
```

iter 변수는 numbers.iter()로부터 생성된 이터레이터를 보유한다. iter.next()는 \&mut self를 통해 내부 상태를 갱신하고, items를 순서대로 꺼내므로 매 호출마다 이터레이터가 한 단계씩 앞으로 나아간다. 모든 요소를 꺼내면 다음 호출부터는 None을 반환한다.

fold 메서드는 이터레이터 내의 모든 아이템을 대상으로 특정 함수 연산을 누적 적용한 뒤 최종 결과를 반환한다. fold가 하는 일을 간단히 말하면 “초깃값 + 반복자 내부의 모든 아이템 + 연산 함수 = 최종 결과”로 요약할 수 있다. 시그니처를 살펴보면 아래와 같이 정의되어 있다.

```rust
fn fold<B, F>(self, init: B, f: F) -> B
where
    F: FnMut(B, Self::Item) -> B,
{
    // 구현부(디폴트 메서드)
}
```

self는 이터레이터를 소비(consume)하면서 내부 요소를 차례대로 꺼내고, init은 누적을 시작할 초기값이다. f는 (누적값, 이터레이터로부터 나온 현재 아이템) 형태의 인자를 받고, 새로운 누적값을 반환하는 함수다. 예시는 다음과 같다.

```rust
let numbers = vec![1, 2, 3, 4, 5];
let sum = numbers.iter().fold(0, |acc, x| acc + x);

// sum은 15가 된다.
```

fold를 직접 사용하는 형태는 while let Some(item) = iter.next() 블록 내부에서 누적값을 계속 업데이트하는 수작업과 동일하다. 그러나 fold로 추상화하면, 반복자에서 값이 하나씩 나오고 그 값이 어떻게 축적되는지를 한눈에 파악하기 쉬워진다.

fold는 단순 합계 외에도 더 복잡한 구조를 생성하거나, 어떤 조건에 따라 결과를 변경하는 로직을 처리할 때도 유용하다. 예컨대 모든 아이템을 문자열로 합치거나, 조건에 따라 다른 자료구조에 삽입하는 식의 동작에도 적용할 수 있다.

```rust
let words = vec!["Rust", "언어", "최고"];
let sentence = words.iter().fold(String::new(), |mut acc, w| {
    acc.push_str(w);
    acc.push(' ');
    acc
});
// sentence: "Rust 언어 최고 "
```

fold의 초기값으로 빈 String을 주고, 각 반복마다 단어를 이어붙여 하나의 문자열을 만드는 예시다. 이처럼 이터레이터가 생산하는 타입과 fold의 초기값, 그리고 연산 함수의 조합을 자유롭게 구성하면 매우 다양한 형태의 누적 작업을 표현할 수 있다.

다른 Iterator 디폴트 메서드인 collect, map, filter 등도 결국 next를 기반으로 구현되며, 체이닝을 통해 가독성과 모듈화를 높일 수 있다. 모든 이터레이터는 내부에서 상태를 갖고, next를 호출할 때마다 그 상태가 변화한다는 점이 공통적이다. fold는 그런 next 호출 과정을 추상화해, 사용자 친화적이고 선언적인 방식으로 누적 로직을 작성할 수 있게 한다.

정리하면, Rust에서 Iterator 트레이트는 반복 로직을 캡슐화하기 위한 핵심 인터페이스이며, next 메서드를 통해 이터레이터의 상태를 진행시키고, fold를 비롯한 디폴트 메서드들은 이러한 반복 과정을 간단하고 직관적으로 구현할 수 있게 돕는다. 이는 러스트 생태계에서 데이터 처리를 더욱 안전하고 간결하게 수행할 수 있는 근간이 된다.
