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

match — 강제로 망라적

~12 min · enums, match, exhaustiveness

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

match 는 Rust 의 제일 강력한 제어 흐름 도구야. 값을 패턴들과 비교해서 맞는 첫 arm 을 돌려 — 근데 그 초능력은 컴파일러가 모든 경우를 덮게 강제한다는 거야.

match 는 표현식이야

if 처럼 match 도 값을 만들어서 결과를 할당할 수 있어. 각 arm 은 패턴 => 표현식 이고. 패턴은 variant 안의 데이터를 바인딩할 수 있어: Some(n) => ... 는 안쪽 값을 n 으로 꺼내서 그 arm 에서 쓸 준비를 해줘.

망라성이 마법이야

match 는 모든 가능한 경우를 처리해야 해, 안 그럼 컴파일 안 돼. Option 에 match 하면서 None 을 까먹어? 컴파일 에러. enum 을 바꾸기 전엔 깐깐하게 들려: variant 를 더하면 컴파일러가 즉시 모든 경우를 더는 안 덮는 모든 match 를 나열해. 리팩터링이 까먹은 자리 사냥이 아니라 안내된 체크리스트가 돼.

망라성이 '경우 까먹음' 을 컴파일 에러로 바꿔. 다른 언어에서 빠진 else 나 처리 안 된 enum 값에 숨는 버그가 여기선 컴파일을 못 버텨. variant 를 더하면 컴파일러가 할 일 목록을 건네줘.

조심해서 쓰는 와일드카드

_ 는 뭐든 매칭하고 '남은 모든 경우' 라고 말하는 법이야. 쓸모 있지만, 미래 variant 에 대한 망라성 검사를 옵트아웃하기도 해 — 새 variant 를 더하면 _ arm 이 조용히 삼켜버려. '나머지 전부' 를 진짜로 뜻할 때 _ 를 써; 나중에 컴파일러가 상기시켜주길 원하면 variant 를 또박또박 적어.

Code

망라적 match, 값 바인딩, 그리고 가드·rust
enum Coin { Penny, Nickel, Dime, Quarter }

fn value(c: Coin) -> u32 {
    match c {                 // 모든 variant 를 반드시 덮어야 함
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

fn main() {
    // match 는 안쪽 데이터를 바인딩하고 표현식이야:
    let maybe = Some(7);
    let described = match maybe {
        Some(n) if n > 5 => format!("big: {n}"), // 가드 있는 arm
        Some(n) => format!("small: {n}"),
        None => String::from("nothing"),
    };
    println!("{} {}", value(Coin::Dime), described);
}

External links

Exercise

네 방위를 enum 으로 쓰고 각각을 (dx, dy) 이동 튜플로 매핑하는 match 를 써봐. 컴파일해. 이제 다섯 번째 variant (예: Stay) 를 enum 엔 더하고 match 엔 안 더하고, 컴파일러 에러를 읽어. 방금 무슨 체크리스트를 건네받았어?
Hint
컴파일러가 match 가 비망라적이라 보고하고 처리 안 된 variant 를 짚어줘. 그게 망라성이 너를 위해 일하는 거야: variant 를 더하는 순간 업데이트 필요한 모든 match 가 플래그돼.

Progress

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

댓글 0

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

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