16.2 Option
& unwrap
마지막 예제에서, 우리가 마음먹으면 프로그램의 실패를 유도할 수 있음을 보여줬다. 우리 프로그램에게 만약 공주가 부적절한 선물 - 뱀 - 을 받았을 경우 panic
하라고 얘기했다. 하지만 공주가 원하는 선물을 받거나 아무것도 받지 못했다면? 이도 나쁜 경우가 되도록, 처리될 필요가 있다!
우리는 null string(""
)을 통해 이를 테스트 할 수 있다. Rust를 사용하고 있으니 선물이 없는 경우를 컴파일러 대신 집어내보자.
std 라이브러리에 있는 Option<T>
로 불리는 enum
이 부재가 가능할 시에 사용된다. 그것은 두 "options" 중 하나로 자신을 나타낸다.
Some(T)
:T
타입의 요소가 발견됐을시None
: 요소가 없을 시
이들 경우들은 match
를 통해 명시적으로 처리 되거나 unwrap
으로 암시적으로 처리 된다. 암시적 처리는 내부 요소를 반환하거나 panic
을 반환한다.
주목할 점은 expect된 수작업으로 사용자 정의 된 panic
이 가능하다는 것, 그런 반면에 unwrap
은 명시적인 처리보다 더 적은 내용의 출력을 남긴다. 다음 예제에서, 원할 경우 panic
옵션을 유지하면서 명시적 처리는 더 제어된 결과를 산출한다.
// 평민은 모든 것을 보았고, 어떤 선물이든 처리할 수 있다.
// 모든 선물은 `match`를 사용해 명시적으로 처리된다.
fn give_commoner(gift: Option<&str>) {
// 각 경우에 따라 처리 과정을 지시한다.
match gift {
Some("snake") => println!("Yuck! I'm throwing that snake in a fire."),
Some(inner) => println!("{}? How nice.", inner),
None => println!("No gift? Oh well."),
}
}
// 우리가 보호하는 공주는 뱀이 보이면 `panic`하게 된다.
// 모든 선물은 `unwrap`을 사용하여 암시적으로 처리된다.
fn give_princess(gift: Option<&str>) {
// `unwrap` returns a `panic` when it receives a `None`.
let inside = gift.unwrap();
if inside == "snake" { panic!("AAAaaaaa!!!!"); }
println!("I love {}s!!!!!", inside);
}
fn main() {
let food = Some("cabbage");
let snake = Some("snake");
let void = None;
give_commoner(food);
give_commoner(snake);
give_commoner(void);
let bird = Some("robin");
let nothing = None;
give_princess(bird);
give_princess(nothing);
}