이 물음표 연산자는 무엇입니까?


답변:


149

아시다시피 Rust에는 예외가 없습니다. 패닉이 있지만 기능이 제한되고 (구조화 된 정보를 전달할 수 없음) 오류 처리에 사용하지 않는 것이 좋습니다 (복구 할 수없는 오류를 의미 함).

Rust에서 오류 처리는 Result. 일반적인 예는 다음과 같습니다.

fn halves_if_even(i: i32) -> Result<i32, Error> {
    if i % 2 == 0 {
        Ok(i / 2)
    } else {
        Err(/* something */)
    }
}

fn do_the_thing(i: i32) -> Result<i32, Error> {
    let i = match halves_if_even(i) {
        Ok(i) => i,
        Err(e) => return Err(e),
    };

    // use `i`
}

다음과 같은 이유로 좋습니다.

  • 코드를 작성할 때 실수로 오류를 처리하는 것을 잊을 수 없습니다.
  • 코드를 읽을 때 바로 여기에서 오류 가능성이 있음을 즉시 알 수 있습니다.

그러나 매우 장황하다는 점에서 이상적이지 않습니다. 이것은 물음표 연산자 ?가 들어오는 곳입니다.

위의 내용은 다음과 같이 다시 작성할 수 있습니다.

fn do_the_thing(i: i32) -> Result<i32, Error> {
    let i = halves_if_even(i)?;

    // use `i`
}

훨씬 더 간결합니다.

어떤 ?여기 않는 것은 동일합니다 match위의 진술. 요컨대 : ResultOK이면 압축을 풀고 그렇지 않으면 오류를 반환 합니다.

그것은 약간의 마술이지만 오류 처리에는 상용구를 줄이기 위해 약간의 마술이 필요하며 예외와 달리 어떤 함수 호출이 오류가 발생할 수 있는지 즉시 볼 수 있습니다 ?.

마법의 한 예는 이것이 다음에서도 작동한다는 것입니다 Option.

// Assume
// fn halves_if_even(i: i32) -> Option<i32>

fn do_the_thing(i: i32) -> Option<i32> {
    let i = halves_if_even(i)?;

    // use `i`
}

이것은 (불안정한) Try특성에 의해 구동됩니다 .

또한보십시오:


5
대답을 조금 확장 할 수 있다면 좋을 것입니다. 예를 들어 함수의 반환 유형이 "언 래핑"하려는 유형 (예 : Result또는) 과 일치해야한다고 논의합니다 Option.
hellow

내가 생각 @hellow이 더 나은 완전히 새로운 질문이 될 것입니다
폴 Razvan 보낸 버그

2

복구 가능한 오류 유형 Result <T, E>에 대한 오류 전파 용입니다. 결과를 풀고 내부 가치를 제공합니다.

오류 사례를 처리하는 대신 호출자 코드에 전파하고 Ok 사례 만 처리합니다. 이점은 많은 상용구를 제거하고 함수 구현을 더 간단하게 만든다는 것입니다.


1
.unwrap()오류가 발생했을 때 당황 하는 실제와 혼동하지 마십시오 .
Jordan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.