18장. 패턴과 매칭

Gillilab - TechLog·2024년 11월 17일

Rust

목록 보기
19/21

18장. 패턴과 매칭

패턴 매칭은 Rust의 강력한 기능 중 하나로, 다양한 데이터 구조를 간결하고 효율적으로 처리할 수 있게 해줍니다. match 키워드를 사용하여 값이 특정 패턴과 일치하는지 검사하고, 각 패턴에 대해 다른 동작을 수행할 수 있습니다.

패턴 매칭 예제

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u32 {
    match coin {
        Coin::Penny => {
            println!("Lucky penny!");
            1
        },
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

fn main() {
    let coin = Coin::Penny;
    println!("The value of the coin is {} cents.", value_in_cents(coin));
}

위 예제에서 Coin 열거형(enum)을 정의하고, 각 동전의 값을 반환하는 value_in_cents 함수를 구현했습니다. match 표현식을 사용하여 coin 값이 어떤 동전인지 검사하고, 그에 따라 다른 값을 반환합니다.

패턴 매칭의 다양한 활용

패턴 매칭은 단순한 값 비교 외에도 다양한 상황에서 유용하게 사용될 수 있습니다.

튜플 매칭

fn main() {
    let pair = (0, -2);

    match pair {
        (0, y) => println!("First is zero and y is {}", y),
        (x, 0) => println!("x is {} and second is zero", x),
        _ => println!("It is a different pair"),
    }
}

구조체 매칭

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 0, y: 7 };

    match p {
        Point { x: 0, y } => println!("On the y axis at {}", y),
        Point { x, y: 0 } => println!("On the x axis at {}", x),
        Point { x, y } => println!("On neither axis: ({}, {})", x, y),
    }
}

열거형 매칭

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

fn main() {
    let msg = Message::ChangeColor(0, 160, 255);

    match msg {
        Message::Quit => println!("The Quit variant has no data to destructure."),
        Message::Move { x, y } => println!("Move in the x direction {} and in the y direction {}", x, y),
        Message::Write(text) => println!("Text message: {}", text),
        Message::ChangeColor(r, g, b) => println!("Change the color to red {}, green {}, and blue {}", r, g, b),
    }
}

패턴 매칭은 Rust의 안전성과 가독성을 높이는 중요한 기능입니다. 다양한 데이터 구조를 다룰 때 패턴 매칭을 활용하면 코드의 명확성과 효율성을 크게 향상시킬 수 있습니다.

Summary

  • 패턴 문법

    • 리터럴 매칭
      • 숫자: match x { 1 => println!("하나"), 2 => println!("둘"), _ => println!("기타") }
      • 문자열: match s { "hello" => println!("안녕"), _ => println!("기타") }
    • 변수 바인딩과 구조 분해
      • 튜플: let (x, y, z) = (1, 2, 3);
      • 구조체: let Point { x, y } = point;
      • 중첩 패턴: let ((x, y), Point { a, b }) = ((1, 2), Point { a: 3, b: 4 });
    • 다중 패턴과 범위
      • OR 패턴: match x { 1 | 2 | 3 => println!("1~3"), _ => println!("기타") }
      • 범위 매칭: match x { 1..=5 => println!("1에서 5사이"), 'a'..='z' => println!("소문자") }
    • 가드 조건: match x { n if n > 0 => println!("양수"), _ => println!("0 또는 음수") }
    • @ 바인딩: match x { n @ 1..=5 => println!("1-5 사이의 값: {}", n), _ => () }
  • 반증 가능성

    • 반증 불가능한 패턴 (항상 매칭됨)
      • 변수 선언: let x = 5;
      • 와일드카드: let _ = value;
    • 반증 가능한 패턴 (매칭이 실패할 수 있음)
      • Option 매칭: if let Some(x) = option_value { ... }
      • Result 매칭: if let Ok(value) = result { ... }
    • 컴파일 시점 안전성
      • let 구문에서는 반증 불가능한 패턴만 허용
      • if let과 while let에서는 반증 가능한 패턴 사용 가능
  • 패턴 매칭의 모든 위치

    • 제어 흐름
      • match 표현식: match value { Some(x) => x + 1, None => 0 }
      • if let 구문: if let Some(x) = option { println!("값: {}", x) }
      • while let 루프: while let Some(value) = stack.pop() { println!("{}", value) }
    • 함수 매개변수
      • 구조체 분해: fn process(Point { x, y }: Point)
      • 튜플 분해: fn process((x, y): (i32, i32))
    • let 구문
      • 슬라이스 패턴: let [first, second, rest @ ..] = array;
      • ref 패턴: let ref r = value; // 값을 이동하지 않고 참조
    • for 루프
      • 이터레이터 분해: for (i, value) in enumerate(iterator) { ... }

참조: https://doc.rust-lang.org/book/ch18-00-patterns.html

0개의 댓글