카테고리 없음

Rust 에러 처리 | Result와 Option 제대로 이해하기

mystory55801 2025. 5. 30. 07:55

Rust 에러 처리 | Result와 Option 제대로 이해하기

Rust는 안전하고 견고한 프로그램을 작성하기 위해 특별한 에러 처리 방식을 제공합니다. 그 중심에는 ResultOption 열거형이 있습니다. 이 두 타입을 잘 이해하면 에러 상황을 안전하게 처리하고, 예외를 효과적으로 관리할 수 있습니다. 이번 글에서는 Rust의 ResultOption 타입의 개념과 활용법을 자세히 알아보겠습니다.

1. Option 타입: 값의 존재 여부 표현

Option<T>는 값이 있을 수도 있고 없을 수도 있는 상황을 표현하는 열거형입니다. 대표적인 변종은 Some(T)None입니다.


fn find_element(arr: &[i32], target: i32) -> Option {
    for (index, &item) in arr.iter().enumerate() {
        if item == target {
            return Some(index);
        }
    }
    None
}

fn main() {
    let numbers = [10, 20, 30];
    match find_element(&numbers, 20) {
        Some(idx) => println!("찾은 인덱스: {}", idx),
        None => println!("값을 찾을 수 없습니다."),
    }
}

2. Result 타입: 성공과 실패 구분하기

Result<T, E>는 작업의 성공(Ok(T))과 실패(Err(E))를 나타내는 열거형입니다. 주로 에러가 발생할 수 있는 함수에서 사용됩니다.


fn divide(a: f64, b: f64) -> Result {
    if b == 0.0 {
        Err(String::from("0으로 나눌 수 없습니다"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 2.0) {
        Ok(result) => println!("나눗셈 결과: {}", result),
        Err(e) => println!("에러 발생: {}", e),
    }
}

3. Option과 Result 활용 시 패턴 매칭

두 타입 모두 match 구문으로 안전하게 처리할 수 있습니다. 이는 예상치 못한 상황을 컴파일 단계에서 예방하는 Rust의 강력한 기능입니다.

4. 편리한 메서드 활용하기

Option과 Result는 다양한 유용한 메서드를 제공합니다. 예를 들어 unwrap(), expect(), map(), and_then() 등을 활용하면 더욱 간결한 코드 작성이 가능합니다.


let some_value = Some(5);
println!("값: {}", some_value.unwrap());

let result: Result = Ok(10);
println!("결과: {}", result.expect("실패했습니다"));

단, unwrap()expect()는 값이 없거나 에러일 때 프로그램이 패닉할 수 있으니 주의가 필요합니다.

5. ? 연산자를 통한 에러 전파

함수 내부에서 여러 에러 처리 코드가 복잡할 때, ? 연산자를 사용하면 에러를 자동으로 호출자에게 전달할 수 있어 코드가 훨씬 간결해집니다.


fn read_number_from_file() -> Result {
    let content = std::fs::read_to_string("number.txt")?;
    let num: i32 = content.trim().parse().map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, "잘못된 숫자"))?;
    Ok(num)
}

결론: Result와 Option으로 안전한 Rust 에러 처리 완성하기

Rust는 OptionResult 타입을 통해 에러 처리와 값의 유무를 명확히 구분하여, 안정적인 코드를 작성할 수 있도록 돕습니다. 패턴 매칭과 다양한 메서드, 그리고 ? 연산자를 적극 활용하면 에러 처리를 더욱 효과적으로 구현할 수 있습니다.

초보자라면 두 타입의 개념부터 차근차근 익히고, 실전 예제를 많이 작성해 보는 것이 중요합니다. 이를 통해 Rust의 안전성과 생산성을 최대한 활용할 수 있을 것입니다.