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

? 소개

때로는 panic의 가능성 없이 unwrap의 단순함만을 원할 때가 있습니다. 지금까지 unwrap은 우리가 정말 원했던 것이 변수를 꺼내는 것임에도 불구하고 점점 더 깊게 중첩하도록 강제해 왔습니다. 이것이 바로 ?의 목적입니다.

Err을 발견했을 때 취할 수 있는 유효한 조치는 두 가지입니다:

  1. 가능하다면 피하기로 이미 결정한 panic!
  2. Err은 처리될 수 없음을 의미하므로 return

?Err에 대해 panic을 일으키는 대신 return하는 unwrap과 거의1 정확히 동일합니다. 콤비네이터를 사용했던 이전 예제를 어떻게 단순화할 수 있는지 봅시다:

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = first_number_str.parse::<i32>()?;
    let second_number = second_number_str.parse::<i32>()?;

    Ok(first_number * second_number)
}

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

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

try! 매크로

?가 나오기 전에는 동일한 기능을 try! 매크로로 구현했습니다. 현재는 ? 연산자가 권장되지만, 오래된 코드를 볼 때 여전히 try!를 발견할 수도 있습니다. 이전 예제의 동일한 multiply 함수는 try!를 사용하면 다음과 같습니다:

// Cargo를 사용하면서 이 예제를 에러 없이 컴파일하고 실행하려면,
// `Cargo.toml` 파일의 `[package]` 섹션에 있는 `edition` 필드 값을 "2015"로 변경하세요.

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = try!(first_number_str.parse::<i32>());
    let second_number = try!(second_number_str.parse::<i32>());

    Ok(first_number * second_number)
}

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

fn main() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

  1. 자세한 내용은 ? 다시 보기를 참조하세요.