17-3. 코드 정제: '대입 피라미드' 허물기 🟡
학습 목표:
- Rust의 식(Expression) 기반 문법과 클로저를 활용하여, 깊게 중첩된
if/else대입문을 깔끔하고 선형적인 코드로 바꾸는 기법을 배웁니다.- '죽음의 피라미드'를 파괴하고 가독성 높은 선언적 코드를 설계하는 법을 익힙니다.
- 즉시 실행 클로저와
?연산자의 조합으로 복잡한 조건 검증을 평탄화합니다.
1. 식(Expression) 기반 대입: "선언과 동시에 확정하기"
C++에서는 여러 조건에 따라 변수 값을 정하기 위해 if 문 내부에서 외부 변수를 수정(Mutate)해야 하는 경우가 많습니다. 하지만 Rust는 if 블록 자체가 값을 반환하는 '식'이므로, 단 한 번의 선언으로 모든 값을 확정할 수 있습니다.
#![allow(unused)] fn main() { // [C++ 스타일: 가변 변수와 다중 대입] let mut code = 0; let mut action = ""; if is_critical { code = 500; action = "STOP"; } else { code = 200; action = "OK"; } // [Rust 스타일: 식을 이용한 원자적 대입] let (code, action) = if is_critical { (500, "STOP") } else { (200, "OK") }; // 모든 변수가 불변(immutable)으로 깔끔하게 선언됨 }
2. 즉시 실행 클로저와 ? 연산자: "중첩 파괴하기"
데이터의 존재 여부를 층층이 확인하는 '검증 피라미드'는 클로저와 ? 연산자를 조합하여 완전히 평탄화할 수 있습니다.
#![allow(unused)] fn main() { // [피라미드 구조: 가독성 저하] if let Some(a) = get_a() { if let Some(b) = a.get_b() { if let Some(c) = b.get_c() { return c; } } } "N/A" // [평탄화된 흐름: 즉시 실행 클로저 활용] let result = (|| { let a = get_a()?; let b = a.get_b()?; let c = b.get_c()?; Some(c) })().unwrap_or("N/A"); }
3. 반복자 체인을 통한 루프 정제
수동으로 루프를 돌며 컬렉션에 데이터를 채우는 코드를 반복자 어댑터로 대체하면, 소유권 관련 버그를 방지하고 핵심 로직의 의도를 명확히 드러낼 수 있습니다.
| 전통적 루프 패턴 | Rust 반복자 대응 | 핵심 효과 |
|---|---|---|
for + if { push } | .filter().collect() | 조건에 맞는 요소만 깔끔하게 추출 |
for { transform + push } | .map().collect() | 데이터 형식의 일괄 변환 |
for { if + break } | .find() / .find_map() | 첫 번째 일치 항목 검색 및 안전한 변환 |
#![allow(unused)] fn main() { // [실전 예시] 실패한 테스트만 골라 이름 리스트 만들기 let failure_names: Vec<_> = test_results.iter() .filter(|t| !t.is_pass) // 1. 탈락자 필터링 .map(|t| t.name.clone()) // 2. 이름만 추출 .collect(); // 3. 최종 수집 (Allocation 최소화) }
💡 실무 설계 팁
- 변수를 미리 선언하고 나중에 채우지 마세요. 대신 식(Expression)을 통해 선언과 동시에 값을 확정하세요.
- 깊은 중첩은 클로저로 감싸세요.
?연산자가 복잡한 중첩을 단 몇 줄의 직관적인 체인으로 바꿔줄 것입니다. - 반복자(Iterator)는 단순한 루프가 아닙니다. 데이터를 흐르게 하고 정제하는 '파이프라인'입니다.
📌 요약
- Rust의 모든 제어문은 값을 반환하는 **식(Expression)**으로 활용할 수 있습니다.
?연산자는Option과Result의 중첩을 허무는 데 탁월한 도구입니다.- 명령형(Imperative) 루프를 선언적(Declarative) 반복자 체인으로 바꾸면 코드가 훨씬 견고해집니다.