match 표현식

Rust에서 제공하는 match 표현식은 패턴 매칭을 통해 값을 분기 처리하는 강력한 제어 흐름 도구이다. 이를 통해 코드 가독성을 높이고 다양한 형태의 분기 처리를 명확하게 표현할 수 있다. 또한 match는 표현식(expression)이기 때문에 값을 반환할 수 있으며, 다른 언어의 switch-case 문과 달리 광범위한 패턴 매칭을 지원한다.

match 표현식은 주어진 값과 일치하는 패턴을 찾아 각각에 대응하는 코드 블록을 실행한다. 모든 패턴 중 하나가 반드시 매칭되어야 하므로, Rust 컴파일러는 모든 경우가 처리되도록 요구한다. 이 특성 덕분에 런타임 오류를 예방하고 안정성을 보장할 수 있다.

아래는 기본적인 match 표현식의 형태이다.

fn main() {
    let number = 3;

    match number {
        1 => println!("값이 1이다."),
        2 => println!("값이 2이다."),
        3 => println!("값이 3이다."),
        _ => println!("값이 1, 2, 3 중 어느 것도 아니다."),
    }
}

여기서 number가 1, 2, 3 중 어느 값인지에 따라 다른 분기가 실행된다. 마지막에 사용된 언더스코어(_) 패턴은 위 패턴들과 일치하지 않는 모든 경우를 처리하기 위한 “포괄적인” 패턴이다.

match 표현식은 분기마다 중괄호로 감싸진 코드 블록을 가질 수도 있다. 패턴에 해당하는 블록은 중괄호 안의 문장들을 수행하며, 각 블록의 끝에는 세미콜론이 붙지 않는다. match 표현식은 실제로 마지막 표현식을 반환하기 때문에 다음과 같이 값을 반환받아 다른 변수에 대입하는 것도 가능하다.

fn main() {
    let number = 5;

    let result = match number {
        1 => {
            println!("1을 입력받았다.");
            "One"
        },
        2 | 3 => {
            println!("2 또는 3을 입력받았다.");
            "Two or Three"
        },
        _ => {
            println!("특정 범위 밖의 값을 입력받았다.");
            "Others"
        }
    };

    println!("매치 결과: {}", result);
}

이 예제에서 match 블록의 각 분기마다 문자열 리터럴을 반환하고, 이 문자열이 result 변수로 할당된다. 또한 2 | 3 과 같은 구문을 통해 여러 패턴을 하나로 묶을 수 있다.

match에서 제공하는 패턴 매칭 기능은 숫자나 단순 리터럴에만 국한되지 않는다. 다음처럼 튜플이나 구조체, 열거형(enum)도 매칭할 수 있다.

Color 열거형 중 Blue를 선택했을 때 매개변수로 넘어온 (r, g, b) 값을 구조 해체(destructuring) 하여 사용할 수 있다. Red나 Green에는 별다른 정보가 없으므로 단순한 패턴만 매칭한다.

match에서 더 복잡한 패턴 매칭을 활용하기 위해서는 매치 가드(match guard)를 사용할 수도 있다. 매치 가드는 if 키워드를 이용하여 패턴에 추가적인 조건을 부여하는 방식이다. 이 기법은 패턴은 같지만 구체적인 값에 따라 다른 동작을 수행해야 할 때 유용하다.

여기서는 number가 짝수인지 여부를 매치 가드로 검사한다. 같은 x라는 패턴이지만 x % 2 == 0인지에 따라 다른 분기가 실행된다. 매치 가드는 복잡한 로직을 효율적으로 처리할 수 있지만, 지나치게 많아지면 가독성이 저하될 수 있다.

match 표현식을 사용할 때 주의해야 할 점은 패턴이 포괄적(exhaustive)이어야 한다는 것이다. 즉, 어떤 값이 오더라도 반드시 매치되는 분기가 존재해야 하며, 이를 만족하지 못하면 컴파일 오류가 발생한다. 이러한 엄격한 규칙 덕분에 개발 과정에서 놓치기 쉬운 예외 케이스를 사전에 방지할 수 있다.

패턴 매칭 문법은 match뿐 아니라 let 문이나 함수 파라미터 등 다양한 곳에서 유사하게 적용된다. 하지만 match 표현식이 제공하는 기능과 엄격성은 제어 흐름을 보다 명확하고 안전하게 만들며, Rust에서의 함수적 프로그래밍 스타일을 지원하는 주요 기둥 중 하나로 꼽힌다.

match 표현식은 조건 분기를 간결하게 표현하고 싶을 때, 변수를 해체(destructure)해야 할 때, 특정 값에 대한 처리를 명시적으로 구분하고 싶을 때 등 여러 상황에 다양하게 활용된다. 다양한 데이터 구조에 대한 매칭과 무조건적인 포괄(exhaustive matching) 속성은 다른 언어들의 switch-case 문과 비교했을 때 Rust의 안전성과 표현력 높은 특징 중 하나로 꼽힌다.

코드를 작성할 때는 가능한 한 match 표현식을 활용해 불필요한 if-else 블록을 줄여 가독성을 높이는 것을 권장한다. 특히 열거형을 다룰 때 match는 거의 필수로 사용되는 표현식이며, Rust 코드를 이해하고 작성하는 데 필수적인 개념이다.

match 표현식에 대한 기초적인 사용법과 패턴 매칭에 대한 감각을 잡아두면, 제어 흐름에서 놓칠 수 있는 다양한 예외 상황을 컴파일 타임에 쉽게 확인할 수 있게 된다. 이를 통해 코드의 안전성과 견고함이 크게 향상된다는 점을 꼭 기억하자.

Last updated