이터레이터 검색
Iterator::find는 이터레이터를 순회하며 어떤 조건을 만족하는 첫 번째 값을 찾는 함수입니다. 조건을 만족하는 값이 없으면 None을 반환합니다. 시그니처는 다음과 같습니다:
pub trait Iterator {
// 반복되는 요소의 타입.
type Item;
// `find`는 `&mut self`를 취하므로 호출자는 빌려지거나
// 수정될 수 있지만, 소비(consume)되지는 않습니다.
fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where
// `FnMut`는 캡처된 변수가 최대 수정될 수 있지만 소비되지는 않음을 의미합니다.
// `&Self::Item`은 클로저에 대한 인자를 참조로 취함을 나타냅니다.
P: FnMut(&Self::Item) -> bool;
}
fn main() {
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
// `vec1.iter()`는 `&i32`를 생성합니다.
let mut iter = vec1.iter();
// `vec2.into_iter()`는 `i32`를 생성합니다.
let mut into_iter = vec2.into_iter();
// `iter()`는 `&i32`를 생성하고, `find`는 서술어(predicate)에 `&Item`을 전달합니다.
// `Item = &i32`이므로 클로저 인자는 `&&i32` 타입을 가지며,
// 우리는 이를 패턴 매칭하여 `i32`로 역참조합니다.
println!("vec1에서 2 찾기: {:?}", iter.find(|&&x| x == 2));
// `into_iter()`는 `i32`를 생성하고, `find`는 서술어에 `&Item`을 전달합니다.
// `Item = i32`이므로 클로저 인자는 `&i32` 타입을 가지며,
// 우리는 이를 패턴 매칭하여 `i32`로 역참조합니다.
println!("vec2에서 2 찾기: {:?}", into_iter.find(|&x| x == 2));
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];
// `array1.iter()`는 `&i32`를 생성합니다
println!("array1에서 2 찾기: {:?}", array1.iter().find(|&&x| x == 2));
// `array2.into_iter()`는 `i32`를 생성합니다
println!("array2에서 2 찾기: {:?}", array2.into_iter().find(|&x| x == 2));
}
Iterator::find는 아이템에 대한 참조를 제공합니다. 하지만 아이템의 인덱스를 원한다면 Iterator::position을 사용하세요.
fn main() {
let vec = vec![1, 9, 3, 3, 13, 2];
// `position`은 이터레이터의 `Item`을 값으로 서술어에 전달합니다.
// `vec.iter()`는 `&i32`를 생성하므로 서술어는 `&i32`를 받으며,
// 우리는 이를 패턴 매칭하여 `i32`로 역참조합니다.
let index_of_first_even_number = vec.iter().position(|&x| x % 2 == 0);
assert_eq!(index_of_first_even_number, Some(5));
// `vec.into_iter()`는 `i32`를 생성하므로 서술어는 `i32`를 직접 받습니다.
let index_of_first_negative_number = vec.into_iter().position(|x| x < 0);
assert_eq!(index_of_first_negative_number, None);
}