Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Result

Result은 발생 가능한 _에러_를 설명하는, Option 타입의 더 풍부한 버전입니다.

즉, Result<T, E>는 다음 두 가지 결과 중 하나를 가질 수 있습니다:

  • Ok(T): 요소 T가 발견됨
  • Err(E): 요소 E와 함께 에러가 발견됨

관례적으로 기대되는 결과는 Ok이며, 기대하지 않은 결과는 Err입니다.

Option과 마찬가지로, Result도 많은 메서드들을 가지고 있습니다. 예를 들어 unwrap()은 요소 T를 내놓거나 panic을 일으킵니다. 케이스 처리를 위해 ResultOption 사이에는 겹치는 많은 콤비네이터들이 있습니다.

Rust로 작업하다 보면 parse() 메서드와 같이 Result 타입을 반환하는 메서드들을 자주 만나게 될 것입니다. 문자열을 다른 타입으로 파싱하는 것이 항상 가능한 것은 아니므로, parse()는 실패 가능성을 나타내는 Result를 반환합니다.

문자열을 parse() 하는 데 성공했을 때와 실패했을 때 어떤 일이 일어나는지 봅시다:

fn multiply(first_number_str: &str, second_number_str: &str) -> i32 {
    // `unwrap()`을 사용하여 숫자를 꺼내봅시다. 문제가 생길까요?
    let first_number = first_number_str.parse::<i32>().unwrap();
    let second_number = second_number_str.parse::<i32>().unwrap();
    first_number * second_number
}

fn main() {
    let twenty = multiply("10", "2");
    println!("두 배는 {}", twenty);

    let tt = multiply("t", "2");
    println!("두 배는 {}", tt);
}

실패한 경우, parse()unwrap()panic을 일으킬 수 있도록 에러를 남깁니다. 게다가 이 panic은 프로그램을 종료시키고 불쾌한 에러 메시지를 제공합니다.

에러 메시지의 품질을 높이려면, 반환 타입에 대해 더 구체적이어야 하며 에러를 명시적으로 처리하는 것을 고려해야 합니다.

main에서 Result 사용하기

Result 타입은 명시적으로 지정될 경우 main 함수의 반환 타입이 될 수도 있습니다. 일반적으로 main 함수는 다음과 같은 형태입니다:

fn main() {
    println!("Hello World!");
}

하지만 main은 반환 타입으로 Result를 가질 수도 있습니다. 만약 main 함수 내에서 에러가 발생하면, 에러 코드를 반환하고 에러의 디버그 표현(Debug 트레이트 사용)을 출력합니다. 다음 예제는 그러한 시나리오를 보여주며 다음 섹션에서 다루는 측면들을 언급합니다.

use std::num::ParseIntError;

fn main() -> Result<(), ParseIntError> {
    let number_str = "10";
    let number = match number_str.parse::<i32>() {
        Ok(number)  => number,
        Err(e) => return Err(e),
    };
    println!("{}", number);
    Ok(())
}