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에서의 map

이전 예제의 multiply에서 패닉을 일으키는 것은 견고한 코드가 아닙니다. 일반적으로 우리는 호출자가 에러에 대응하는 올바른 방법을 결정할 수 있도록 에러를 호출자에게 반환하기를 원합니다.

먼저 우리가 어떤 종류의 에러 타입을 다루고 있는지 알아야 합니다. Err 타입을 결정하기 위해, i32에 대해 FromStr 트레이트로 구현된 parse()를 살펴봅니다. 그 결과, Err 타입은 ParseIntError로 지정됩니다.

아래 예제에서, 단순한 match 문은 전체적으로 더 번거로운 코드로 이어집니다.

use std::num::ParseIntError;

// 반환 타입을 다시 작성했으므로, `unwrap()` 없이 패턴 매칭을 사용합니다.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    match first_number_str.parse::<i32>() {
        Ok(first_number)  => {
            match second_number_str.parse::<i32>() {
                Ok(second_number)  => {
                    Ok(first_number * second_number)
                },
                Err(e) => Err(e),
            }
        },
        Err(e) => Err(e),
    }
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n은 {}입니다", n),
        Err(e) => println!("에러: {}", e),
    }
}

fn main() {
    // 이는 여전히 합리적인 답을 제시합니다.
    let twenty = multiply("10", "2");
    print(twenty);

    // 다음은 이제 훨씬 더 도움이 되는 에러 메시지를 제공합니다.
    let tt = multiply("t", "2");
    print(tt);
}

다행히도 Optionmap, and_then 및 다른 많은 콤비네이터들이 Result에 대해서도 구현되어 있습니다. Result 문서에 전체 목록이 나와 있습니다.

use std::num::ParseIntError;

// `Option`과 마찬가지로 `map()`과 같은 콤비네이터를 사용할 수 있습니다.
// 이 함수는 위와 동일하며 다음과 같이 읽힙니다:
// 두 값 모두 문자열에서 파싱될 수 있으면 곱하고, 그렇지 않으면 에러를 넘깁니다.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    first_number_str.parse::<i32>().and_then(|first_number| {
        second_number_str.parse::<i32>().map(|second_number| first_number * second_number)
    })
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n은 {}입니다", n),
        Err(e) => println!("에러: {}", e),
    }
}

fn main() {
    // 이는 여전히 합리적인 답을 제시합니다.
    let twenty = multiply("10", "2");
    print(twenty);

    // 다음은 이제 훨씬 더 도움이 되는 에러 메시지를 제공합니다.
    let tt = multiply("t", "2");
    print(tt);
}