🦀
타입 시스템
타입 시스템 · 선수: 12강
13. 패턴 매칭 (match·if let·while let)
Rust 의 패턴 매칭은 다른 언어의 switch 와 격이 다릅니다 — 값 비교뿐 아니라 구조 분해·가드 조건·ref/mut 바인딩까지 한 문법으로. 이 강의에서 match arm 의 다양한 패턴, 가드, range, OR 패턴, 그리고 자주 쓰이는 if let / while let 까지 정리합니다.
Rustmatchpatternif letwhile letguard
소요 시간
⏱ 약 1.5시간
난이도
📊 중급
선수 조건
🎯 12강
결과물
Rust 의 패턴 매칭은 다른 언어의 switch 와 격이 다릅니다 — 값 비교뿐 아니라 구조 분해·가드 조건·ref/mut 바인딩까지 한 문법으로. 이 강의에서 match arm 의 다양한 패턴, 가드, range, OR 패턴, 그리고 자주 쓰이는 if let / while let 까지 정리합니다.
이 강의에서 배우는 것
- 1리터럴·변수·와일드카드·범위·OR 패턴을 구분한다
- 2tuple·struct·enum 을 패턴으로 분해한다
- 3match arm 에 if 가드를 붙인다
- 4if let 으로 한 variant 만 짧게 처리한다
- 5while let 으로 iterator 의 Some 동안 반복한다
소개
패턴 매칭은 Rust 코드를 짧고 안전하게 만드는 핵심 도구입니다. "값을 분해해서 조건마다 다른 처리" 가 한 표현 안에 들어가니, 임시 변수가 줄고 의도가 한눈에 들어옵니다.
핵심 개념
1) match 의 기본 arm 패턴
| 패턴 | 예 | 의미 |
|---|---|---|
| 리터럴 | 1, "hi" | 값 일치 |
| 변수 | x | 어떤 값이든 잡아 x 에 바인딩 |
| 와일드카드 | _ | 어떤 값이든, 바인딩 안 함 |
| 범위 | 1..=5 | 1~5 |
| OR | 1 | 2 | 3 | 셋 중 하나 |
| 분해 | Point { x, y } | 구조 분해 |
2) match 는 식이며 모든 경우 처리 강제
결과값을 가질 수 있고, 빠뜨린 variant 가 있으면 컴파일 에러. **non-exhaustive patterns** 메시지가 익숙해질 겁니다.
3) 가드 — match arm 에 if 조건
rust
match n {
x if x < 0 => println!("음수"),
0 => println!("영"),
x => println!("양수 {}", x),
}4) if let / while let — 한 variant 만 관심
match 의 한 arm 만 처리하면 충분할 때 짧게 쓰는 syntactic sugar.
핵심 예제
tuple·enum 분해와 가드:
rust
fn classify(p: (i32, i32)) -> &'static str {
match p {
(0, 0) => "원점",
(x, 0) if x > 0 => "양의 x축",
(x, 0) => "음의 x축",
(0, y) if y > 0 => "양의 y축",
(0, _) => "음의 y축",
(x, y) if x == y => "y=x 위",
_ => "기타",
}
}
fn main() {
for p in [(0,0),(3,0),(0,-2),(5,5),(2,7)] {
println!("{:?} → {}", p, classify(p));
}
}if let — 한 variant 처리:
rust
let some_val: Option<i32> = Some(7);
if let Some(n) = some_val {
println!("got {}", n);
} else {
println!("none");
}while let — iterator 의 Some 동안:
rust
fn main() {
let mut stack = vec![1, 2, 3, 4];
while let Some(top) = stack.pop() {
println!("{}", top); // 4, 3, 2, 1
}
}@ 바인딩 — 값 검사하면서 동시에 캡처:
rust
let n = 42;
match n {
x @ 1..=50 => println!("1~50 사이의 {}", x),
_ => println!("범위 밖"),
}자주 하는 실수
Q. _ 와 변수명을 안 쓰는 차이가 뭔가요?
A. `_` 는 값을 받지 않고 버립니다(바인딩 X). 변수명은 값을 잡아 바인딩하므로 가드·우변에서 사용 가능.
Q. 모든 variant 가 너무 많아요. _ 만 쓰면 안 되나요?
A. 됩니다만, 새 variant 가 추가됐을 때 컴파일러가 잡아주는 안전망이 사라집니다. 가능한 명시적으로.
Q. if let 에 else 가 있나요?
A. 있습니다. `if let Some(x) = opt { ... } else { ... }` 형태로. let-else 라는 다른 문법도 있어 변수 바인딩을 함수 본문 흐름으로 풀어내기 좋습니다.
정리
- match 는 식, 모든 경우 처리 강제
- 리터럴·변수·와일드카드·범위·OR·분해·@ 바인딩 모두 가능
- 가드(if) 로 조건 추가
- if let / while let / let-else 로 짧게 쓸 수 있음
과제
- enum Direction { Up, Down, Left, Right } 를 만들고 match 로 (dx, dy) 튜플 반환
- Vec<Option<i32>> 를 받아 Some 값만 추출하는 함수 작성 (while let / for 어느 쪽이든)
- @ 바인딩을 활용해 1~9 / 10~99 / 100+ 범위를 분류하면서 동시에 값을 캡처해 출력