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

?로 옵션 풀기

match 문을 사용하여 Option을 풀 수(unpack) 있지만, ? 연산자를 사용하는 것이 더 쉬울 때가 많습니다. 만약 xOption이라면, x?를 평가할 때 xSome이면 그 내부 값을 반환하고, 그렇지 않으면 실행 중인 함수를 종료하고 None을 반환합니다.

fn next_birthday(current_age: Option<u8>) -> Option<String> {
    // 만약 `current_age`가 `None`이면, 이는 `None`을 반환합니다.
    // 만약 `current_age`가 `Some`이면, 내부의 `u8` 값 + 1이
    // `next_age`에 할당됩니다.
    let next_age: u8 = current_age? + 1;
    Some(format!("내년에 저는 {}살이 됩니다", next_age))
}

여러 개의 ?를 체인으로 연결하여 코드를 훨씬 더 읽기 쉽게 만들 수 있습니다.

struct Person {
    job: Option<Job>,
}

#[derive(Clone, Copy)]
struct Job {
    phone_number: Option<PhoneNumber>,
}

#[derive(Clone, Copy)]
#[allow(dead_code)]
struct PhoneNumber {
    area_code: Option<u8>,
    number: u32,
}

impl Person {

    // 사람의 직장 전화번호의 지역 번호가 존재한다면 가져옵니다.
    fn work_phone_area_code(&self) -> Option<u8> {
        // `?` 연산자가 없다면 많은 중첩된 `match` 문이 필요했을 것입니다.
        // 훨씬 더 많은 코드가 필요할 것입니다 - 직접 작성해 보고 어느 쪽이 더 쉬운지
        // 확인해 보세요.
        self.job?.phone_number?.area_code
    }
}

fn main() {
    let p = Person {
        job: Some(Job {
            phone_number: Some(PhoneNumber {
                area_code: Some(61),
                number: 439222222,
            }),
        }),
    };

    assert_eq!(p.work_phone_area_code(), Some(61));
}