Rust 기초부터 마스터까지 — 6화
컬렉션, 반복자, 클로저로 데이터 처리하기
본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.
Rust 표준 컬렉션은 자신이 저장한 값을 소유한다. 반복자는 컬렉션을 읽거나 빌리거나 소비하는 방식을 타입으로 구분한다.
Vec와 HashMap
use std::collections::HashMap;
let mut party = Vec::new();
party.push(String::from("Rose"));
let mut items = HashMap::new();
items.insert(10, String::from("Potion"));
if let Some(name) = items.get(&10) {
println!("{name}");
}
Vec는 순서 있는 목록이고 HashMap은 키로 값을 찾는다. get은 값이 없을 수 있으므로 Option을 반환한다.
컬렉션이 재할당되거나 변경되는 동안 내부 원소 참조를 계속 유지하지 못하게 빌림 검사기가 막아준다.
반복자의 소유 방식
for name in &party {
println!("{name}");
}
for name in &mut party {
name.push_str("_01");
}
&party는 원소를 불변으로 빌리고 &mut party는 변경 가능하게 빌린다. party 자체를 값으로 반복하면 원소의 소유권이 이동해 이후 원본을 사용할 수 없다.
반복자와 클로저
let mut alive: Vec<&Monster> = monsters
.iter()
.filter(|monster| monster.health > 0)
.collect();
alive.sort_by_key(|monster| monster.health);
iter는 원소를 빌리는 반복자를 만들고 filter는 조건에 맞는 값만 통과시킨다. collect가 호출될 때 최종 컬렉션이 만들어진다.
let bonus = 5;
let add_bonus = |damage: i32| damage + bonus;
클로저는 주변 값을 빌리거나 이동해 캡처할 수 있다. 클로저가 원래 범위보다 오래 살아야 한다면 move가 필요한지와 소유권이 어디로 가는지 확인해야 한다.
반복자 코드는 무조건 빠르기 때문에 쓰는 것이 아니다. 소유와 빌림 방식을 지키면서 필터와 변환의 의도를 단계로 표현할 수 있다는 점이 장점이다.