이터레이터
Iterator 트레이트는 배열과 같은 컬렉션에 대한 이터레이터를 구현하는 데 사용됩니다.
이 트레이트는 next 요소에 대해 정의될 메서드 하나만을 필요로 하며, 이는 impl 블록에서 수동으로 정의하거나 (배열 및 범위와 같이) 자동으로 정의될 수 있습니다.
일반적인 상황에서의 편의를 위해, for 구문은 .into_iter() 메서드를 사용하여 일부 컬렉션을 이터레이터로 변환합니다.
struct Fibonacci {
curr: u32,
next: u32,
}
// `Fibonacci`에 대해 `Iterator`를 구현합니다.
// `Iterator` 트레이트는 `next` 요소에 대해 정의될 메서드 하나와,
// 이터레이터의 반환 타입을 선언하기 위한 `연관 타입(associated type)`만을 필요로 합니다.
impl Iterator for Fibonacci {
// `Self::Item`을 사용하여 이 타입을 참조할 수 있습니다.
type Item = u32;
// 여기서리는 `.curr`와 `.next`를 사용하여 수열을 정의합니다.
// 반환 타입은 `Option<T>`입니다:
// * 이터레이터가 끝나면 `None`이 반환됩니다.
// * 그렇지 않으면 다음 값이 `Some`으로 감싸져서 반환됩니다.
// 반환 타입에 `Self::Item`을 사용하므로, 함수 시그니처를 업데이트할 필요 없이
// 타입을 변경할 수 있습니다.
fn next(&mut self) -> Option<Self::Item> {
let current = self.curr;
self.curr = self.next;
self.next = current + self.next;
// 피보나치 수열에는 끝이 없으므로, 이 `Iterator`는
// 결코 `None`을 반환하지 않으며 항상 `Some`이 반환됩니다.
Some(current)
}
}
// 피보나치 수열 생성기를 반환합니다.
fn fibonacci() -> Fibonacci {
Fibonacci { curr: 0, next: 1 }
}
fn main() {
// `0..3`은 0, 1, 2를 생성하는 `Iterator`입니다.
let mut sequence = 0..3;
println!("0..3에 대한 네 번의 연속적인 `next` 호출");
println!("> {:?}", sequence.next());
println!("> {:?}", sequence.next());
println!("> {:?}", sequence.next());
println!("> {:?}", sequence.next());
// `for`는 `None`이 반환될 때까지 `Iterator`를 통해 작동합니다.
// 각 `Some` 값은 래핑이 해제되어 변수(여기서는 `i`)에 바인딩됩니다.
println!("`for`를 사용하여 0..3을 순회합니다");
for i in 0..3 {
println!("> {}", i);
}
// `take(n)` 메서드는 `Iterator`를 처음 `n`개의 항으로 줄입니다.
println!("피보나치 수열의 처음 네 항은 다음과 같습니다: ");
for i in fibonacci().take(4) {
println!("> {}", i);
}
// `skip(n)` 메서드는 처음 `n`개의 항을 버리고 `Iterator`를 단축시킵니다.
println!("피보나치 수열의 다음 네 항은 다음과 같습니다: ");
for i in fibonacci().skip(4).take(4) {
println!("> {}", i);
}
let array = [1u32, 3, 3, 7];
// `iter` 메서드는 배열/슬라이스에 대한 `Iterator`를 생성합니다.
println!("다음 배열 {:?}을 순회합니다", &array);
for i in array.iter() {
println!("> {}", i);
}
}