if let
で簡潔な制御フロー
if let
記法でif
とlet
をより冗長性の少ない方法で組み合わせ、残りを無視しつつ、一つのパターンにマッチする値を扱うことができます。
Option<u8>
にマッチするけれど、値が3の時にだけコードを実行したい、リスト6-6のプログラムを考えてください。
#![allow(unused)] fn main() { let some_u8_value = Some(0u8); match some_u8_value { Some(3) => println!("three"), _ => (), } }
Some(3)
にマッチした時だけ何かをし、他のSome<u8>
値やNone
値の時には何もしたくありません。
match
式を満たすためには、列挙子を一つだけ処理した後に_ => ()
を追加しなければなりません。
これでは、追加すべき定型コードが多すぎます。
その代わり、if let
を使用してもっと短く書くことができます。以下のコードは、
リスト6-6のmatch
と同じように振る舞います:
#![allow(unused)] fn main() { let some_u8_value = Some(0u8); if let Some(3) = some_u8_value { println!("three"); } }
if let
という記法は等号記号で区切られたパターンと式を取り、式がmatch
に与えられ、パターンが最初のアームになったmatch
と、
同じ動作をします。
if let
を使うと、タイプ数が減り、インデントも少なくなり、定型コードも減ります。しかしながら、
match
では強制された包括性チェックを失ってしまいます。match
かif let
かの選択は、
特定の場面でどんなことをしたいかと簡潔性を得ることが包括性チェックを失うのに適切な代償となるかによります。
言い換えると、if let
は値が一つのパターンにマッチした時にコードを走らせ、
他は無視するmatch
への糖衣構文と考えることができます。
if let
では、else
を含むこともできます。else
に入るコードブロックは、
if let
とelse
に等価なmatch
式の_
の場合に入るコードブロックと同じになります。
リスト6-4のCoin
enum定義を思い出してください。ここでは、Quarter
列挙子は、
UsState
の値も保持していましたね。クォーターコインの状態を告げつつ、
見かけたクォーター以外のコインの枚数を数えたいなら、以下のようにmatch
式で実現することができるでしょう:
#![allow(unused)] fn main() { #[derive(Debug)] enum UsState { Alabama, Alaska, } enum Coin { Penny, Nickel, Dime, Quarter(UsState), } let coin = Coin::Penny; let mut count = 0; match coin { // {:?}州のクォーターコイン Coin::Quarter(state) => println!("State quarter from {:?}!", state), _ => count += 1, } }
または、以下のようにif let
とelse
を使うこともできるでしょう:
#![allow(unused)] fn main() { #[derive(Debug)] enum UsState { Alabama, Alaska, } enum Coin { Penny, Nickel, Dime, Quarter(UsState), } let coin = Coin::Penny; let mut count = 0; if let Coin::Quarter(state) = coin { println!("State quarter from {:?}!", state); } else { count += 1; } }
match
を使って表現するには冗長的すぎるロジックがプログラムにあるようなシチュエーションに遭遇したら、
if let
もRust道具箱にあることを思い出してください。
まとめ
これで、enumを使用してワンセットの列挙された値のどれかになりうる独自の型を生成する方法を講義しました。
標準ライブラリのOption<T>
が型システムを使用して、エラーを回避する際に役立つ方法についても示しました。
enumの値がデータを内部に含む場合、処理すべきケースの数に応じて、match
かif let
を使用して値を取り出し、
使用できます。
もうRustプログラムで構造体とenumを使用して、自分の領域の概念を表現できます。API内で使用するために独自の型を生成することで、 型安全性を保証することができます: コンパイラが、各関数の予期する型の値のみを関数が得ることを確かめてくれるのです。
使用するのに率直な整理整頓されたAPIをユーザに提供し、ユーザが必要とするものだけを公開するために、 今度は、Rustのモジュールに目を向けてみましょう。