論駁可能性: パターンが合致しないかどうか
パターンには2つの形態があります: 論駁可能なものと論駁不可能なものです。渡される可能性のあるあらゆる値に合致するパターンは、
論駁不可能なものです。文let x = 5;
のx
は一例でしょう。x
は何にでも合致し、故に合致に失敗することがあり得ないからです。
なんらかの可能性のある値に対して合致しないことがあるパターンは、論駁可能なものです。
一例は、式if let Some(x) = a_value
のSome(x)
になるでしょう; a_value
変数の値がSome
ではなく、
None
なら、Some(x)
パターンは合致しないでしょうから。
関数の引数、let
文、for
ループは、値が合致しなかったら何も意味のあることをプログラムが実行できないので、
論駁不可能なパターンしか受け付けられません。if let
とwhile let
式は、定義により失敗する可能性を処理することを意図したものなので、
論駁可能なパターンのみを受け付けます: 条件式の機能は、成功か失敗によって異なる振る舞いをする能力にあるのです。
一般的に、論駁可能と論駁不可能なパターンの差異について心配しなくてもいいはずです; しかしながら、 エラーメッセージで見かけた際に対応できるように、論駁可能性の概念に確かに慣れておく必要があります。 そのような場合には、コードの意図した振る舞いに応じて、パターンかパターンを使用している構文を変える必要があるでしょう。
コンパイラが論駁不可能なパターンを必要とする箇所で論駁可能なパターンを使用しようとしたら、何が起きるかとその逆の例を見ましょう。
リスト18-8はlet
文を示していますが、パターンにはSome(x)
と指定し、論駁可能なパターンです。
ご想像通りかもしれませんが、このコードはコンパイルできません。
let Some(x) = some_option_value;
some_option_value
がNone
値だったなら、パターンSome(x)
に合致しないことになり、パターンが論駁可能であることを意味します。
ですが、let
文は論駁不可能なパターンしか受け付けられません。None
値に対してコードができる合法なことは何もないからです。
コンパイル時にコンパイラは、論駁不可能なパターンが必要な箇所に論駁可能なパターンを使用しようとしたと文句を言うでしょう:
error[E0005]: refutable pattern in local binding: `None` not covered
(エラー: ローカル束縛に論駁可能なパターン: `None`がカバーされていません)
-->
|
3 | let Some(x) = some_option_value;
| ^^^^^^^ pattern `None` not covered
パターンSome(x)
で全ての合法な値をカバーしなかった(できませんでした!)ので、
コンパイラは当然、コンパイルエラーを生成します。
論駁不可能なパターンが必要な箇所に論駁可能なパターンがある問題を修正するには、パターンを使用するコードを変えればいいのです:
let
の代わりにif let
を使用できます。そして、パターンが合致しなかったら、コードは合法に継続する手段を残して、
波括弧内のコードを飛ばすだけでしょう。リスト18-9は、リスト18-8のコードの修正方法を示しています。
# #![allow(unused_variables)] #fn main() { # let some_option_value: Option<i32> = None; if let Some(x) = some_option_value { println!("{}", x); } #}
コードに逃げ道を与えました!このコードは完全に合法ですが、エラーを受け取らないで論駁不可能なパターンを使用することはできないことを意味します。
リスト18-10のように、x
のような常にマッチするパターンをif let
に与えたら、コンパイルできないでしょう。
if let x = 5 {
println!("{}", x);
};
コンパイラは、論駁不可能なパターンとif let
を使用するなんて道理が通らないと文句を言います:
error[E0162]: irrefutable if-let pattern
(エラー: 論駁不可能なif-letパターン)
--> <anon>:2:8
|
2 | if let x = 5 {
| ^ irrefutable pattern
このため、マッチアームは、論駁不可能なパターンで残りのあらゆる値に合致すべき最後のアームを除いて、
論駁可能なパターンを使用しなければなりません。コンパイラは、たった1つしかアームのないmatch
で論駁不可能なパターンを使用させてくれますが、
この記法は特別有用なわけではなく、より単純なlet
文に置き換えることもできるでしょう。
今やパターンを使用すべき箇所と論駁可能と論駁不可能なパターンの違いを知ったので、 パターンを生成するために使用できる全ての記法を講義しましょう。