C.W.K.
Stream
Lesson 05 of 06 · published

이터레이터 & Adapter

~12 min · collections, iterators, adapters, lazy

Level 0Rust 호기심러
0 XP0/80 lessons0/19 achievements
0/100 XP to next level100 XP to go0% complete

이터레이터는 Rust 가 루프를 안 쓰고 루프를 도는 법이야. Traits 트랙에서 만난 Iterator trait 이 adapterconsumer 의 어휘 전체를 움직여, 어떻게 계산할지가 아니라 뭘 원하는지의 서술처럼 읽히는.

이터레이터 얻기

컬렉션을 순회하는 세 방법: .iter() 는 공유 참조 (&T) 를, .iter_mut() 은 가변 참조 (&mut T) 를, .into_iter() 은 컬렉션을 소비하며 소유 T 를 내놔. 뭘 고르냐는 — 또 — 소유권 질문이야: 읽으려고 빌리고, 수정하려고 가변 빌리고, 소유하려고 소비.

Adapter vs consumer

map, filter, take, skip 같은 adapter 는 한 이터레이터를 다른 걸로 변형해 — 그리고 lazy 해, 구동되기 전엔 아무 일도 안 해. collect, sum, count, fold, 또는 for 루프 같은 consumer 가 실제로 값을 끌어당겨 결과를 내. consumer 없는 adapter 체인은 아예 아무것도 안 해.

Adapter 는 lazy; consumer 가 일을 구동해. v.iter().map(f).filter(g) 는 레시피를 짓고 아무것도 안 돌려. .collect().sum() 을 더하면 체인 전체가 단일 패스로 실행되고, adapter 들이 합쳐져 — 중간 벡터 없이, 손으로 쓴 루프만큼 빠르게.

왜 루프보다 이터레이터를 선호하냐

이터레이터 체인은 원하는지 말해 — '짝수의 제곱들' — 인덱스 루프는 어떻게 계산할지 말하고, off-by-one 버그 여지를 남겨. 이터레이터는 zero-cost 이기도 해: 컴파일러가 체인을 손으로 쓴 루프랑 같은 기계어로, 종종 더 빠르게 최적화해. clippy 가 적극적으로 수동 루프에서 이터레이터 체인으로 너를 떠밀어.

Code

sum() 이 구동하는 lazy adapter 체인·rust
fn main() {
    let nums = vec![1, 2, 3, 4, 5, 6];

    // lazy adapter + 구동하는 consumer (sum):
    let sum_of_even_squares: i32 = nums
        .iter()                   // &i32
        .filter(|&&n| n % 2 == 0) // 짝수 유지
        .map(|&n| n * n)          // 제곱
        .sum();                   // consumer: 체인 전체를 한 패스로 실행
    println!("{sum_of_even_squares}"); // 4 + 16 + 36 = 56
}

External links

Exercise

Vec<i32> 가 주어지면, 음수를 유지하고, 절댓값을 취하고, 새 Vec<i32> 로 collect 하는 체인을 지어. .collect() 전엔 아무것도 안 도는 걸 확인해. 그다음 같은 로직을 수동 push 하는 명령형 for 루프로 써 — 어느 게 너한테 더 명확히 읽히고, clippy 는 뭘 선호할까?
Hint
.iter().filter(...).map(...).collect() 체인은 선언적이고 한 패스로 합쳐져. clippy 는 수동 루프보다 이터레이터 체인을 떠미는데, 틀리기 더 어렵고 똑같이 빠르거든.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.