← Rust 강의 목록으로
🦀
타입 시스템
타입 시스템 · 선수: 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..=51~5
OR1 | 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 로 짧게 쓸 수 있음

과제

  1. enum Direction { Up, Down, Left, Right } 를 만들고 match 로 (dx, dy) 튜플 반환
  2. Vec<Option<i32>> 를 받아 Some 값만 추출하는 함수 작성 (while let / for 어느 쪽이든)
  3. @ 바인딩을 활용해 1~9 / 10~99 / 100+ 범위를 분류하면서 동시에 값을 캡처해 출력
예제 코드 / 강의 자료

전체 강의 자료와 예제 코드는 GitHub에서 자유롭게 받아볼 수 있습니다.

GitHub에서 보기 ↗