Rust by Example

16.1 Optionとunwrap

先ほど、ヘビがお姫様への贈り物として適切でないことを確定させました。しかし、お姫様が贈り物を受け取ろうとした際に、何もなかったらどうなるのでしょう?その状況も同程度に望ましくないので、適切に対処する必要があります。値の欠如が可能性として考えられる場合、stdライブラリのOption<T>という列挙型が用いられます。これは、以下の2つの型を取りうるように定義されています。

  • Some(T): 型Tの値がある場合
  • None: 値が存在しない場合。

これらはmatchを用いて明示的に扱うこともできますし、unwrapで暗黙に処理することもできます。後者はSomeの中の値を返すかpanicするかのどちらかです。

expectメソッドを用いて、panicを手動でカスタマイズできることに触れておきましょう。これは(unwrapをそのまま用いた場合よりも)内容が理解しやすいエラーメッセージを出力するのに役立ちます。次の例では、結果をより明示的に、可能ならいつでもpanicできるように扱っていきます。

// 庶民(commoner)は経験豊富なので、大体どんな状況にも対処できます。 // あらゆる贈り物は`match`を用いて手動で処理されます。 fn give_commoner(gift: Option<&str>) { // Specify a course of action for each case. 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`します。 fn give_princess(gift: Option<&str>) { // `unwrap`を使用すると値が`None`だった際に`panic`を返します。。 let inside = gift.unwrap(); if inside == "snake" { panic!("AAAaaaaa!!!!"); } println!("I love {}s!!!!!", inside); } fn main() { let food = Some("chicken"); 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); }