はじめに
反証可能性:パターンが一致しない可能性があるかどうかへようこそ。この実験は、Rust Bookの一部です。LabEx で Rust のスキルを練習することができます。
この実験では、パターンにおける反証可能性の概念と、それが Rust のマッチングプロセスにどのように影響するかを学びます。これには、反証可能なパターンと反証不可能なパターンの違い、およびlet
文やif let
式などのさまざまな構文でそれらを正しく使用する方法が含まれます。
This tutorial is from open-source community. Access the source code
💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください
反証可能性:パターンが一致しない可能性があるかどうかへようこそ。この実験は、Rust Bookの一部です。LabEx で Rust のスキルを練習することができます。
この実験では、パターンにおける反証可能性の概念と、それが Rust のマッチングプロセスにどのように影響するかを学びます。これには、反証可能なパターンと反証不可能なパターンの違い、およびlet
文やif let
式などのさまざまな構文でそれらを正しく使用する方法が含まれます。
パターンには 2 つの形式があります。反証可能なパターンと反証不可能なパターンです。渡される任意の可能な値に対して一致するパターンは、反証不可能なパターンです。例としては、let x = 5;
という文のx
です。なぜならx
は何にでも一致するため、一致しないことはありません。一部の可能な値に対して一致しない可能性のあるパターンは、反証可能なパターンです。例としては、if let Some(x) = a_value
という式のSome(x)
です。なぜなら、a_value
変数の値がNone
である場合、Some(x)
パターンは一致しないからです。
関数のパラメータ、let
文、およびfor
ループは、値が一致しない場合に何も意味のあることができないため、反証不可能なパターンのみを受け付けます。if let
およびwhile let
式は、反証可能なパターンと反証不可能なパターンの両方を受け付けますが、コンパイラは反証不可能なパターンに対して警告を出します。なぜなら、定義上、それらは失敗の可能性を処理するために意図されているからです。条件分岐の機能は、成功または失敗に応じて異なる動作を行う能力にあります。
一般的に、反証可能なパターンと反証不可能なパターンの違いを心配する必要はありません。ただし、反証可能性の概念に慣れておく必要があります。そうすれば、エラーメッセージでそれを見たときに対応できます。そのような場合、コードの意図された動作に応じて、パターンまたはパターンを使用している構文のいずれかを変更する必要があります。
Rust が反証不可能なパターンを必要とする場合に反証可能なパターンを使用しようとしたとき、およびその逆の場合に何が起こるかを見てみましょう。リスト 18-8 はlet
文を示していますが、パターンとして、反証可能なパターンであるSome(x)
を指定しています。予想通り、このコードはコンパイルされません。
let Some(x) = some_option_value;
リスト 18-8:let
に反証可能なパターンを使用しようとする
some_option_value
がNone
の値である場合、パターンSome(x)
と一致しなくなります。これは、パターンが反証可能であることを意味します。ただし、let
文は反証不可能なパターンのみを受け付けることができます。なぜなら、None
の値ではコードが何も有効なことをできないからです。コンパイル時に、Rust は反証不可能なパターンが必要な場所で反証可能なパターンを使用しようとしたことをコンパイラエラーとして通知します。
error[E0005]: refutable pattern in local binding: `None` not covered
--> src/main.rs:3:9
|
3 | let Some(x) = some_option_value;
| ^^^^^^^ pattern `None` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or
an `enum` with only one variant
= note: for more information, visit
https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Option<i32>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
3 | let x = if let Some(x) = some_option_value { x } else { todo!() };
| ++++++++++ ++++++++++++++++++++++
パターンSome(x)
ですべての有効な値をカバー(およびカバーできなかった!)していないため、Rust は正しくコンパイラエラーを生成します。
反証不可能なパターンが必要な場所に反証可能なパターンがある場合、パターンを使用するコードを変更することで修正できます。let
を使用する代わりに、if let
を使用することができます。そうすると、パターンが一致しない場合、コードは波括弧内のコードをスキップし、正常に続行する方法が与えられます。リスト 18-9 は、リスト 18-8 のコードを修正する方法を示しています。
if let Some(x) = some_option_value {
println!("{x}");
}
リスト 18-9:let
の代わりにif let
と反証可能なパターンを持つブロックを使用する
コードに抜け道があります!このコードは完全に有効です。ただし、エラーを受け取らずに反証不可能なパターンを使用することはできません。リスト 18-10 に示すように、if let
に常に一致するパターン(たとえばx
)を与えると、コンパイラは警告を出します。
if let x = 5 {
println!("{x}");
};
リスト 18-10:if let
に反証不可能なパターンを使用しようとする
Rust は、反証不可能なパターンを持つif let
を使用することは意味がないとコンパイラエラーを表示します。
warning: irrefutable `if let` pattern
--> src/main.rs:2:8
|
2 | if let x = 5 {
| ^^^^^^^^^
|
= note: `#[warn(irrefutable_let_patterns)]` on by default
= note: this pattern will always match, so the `if let` is
useless
= help: consider replacing the `if let` with a `let`
このため、match
のアームは、最後のアームを除き、反証可能なパターンを使用する必要があります。最後のアームは、反証不可能なパターンで残りのすべての値と一致する必要があります。Rust は、1 つのアームしか持たないmatch
で反証不可能なパターンを使用することを許可していますが、この構文は特に役に立たず、より単純なlet
文に置き換えることができます。
これで、パターンを使用する場所と反証可能なパターンと反証不可能なパターンの違いがわかりました。次に、パターンを作成するために使用できるすべての構文を説明します。
おめでとうございます!「反証可能性:パターンが一致しない可能性があるかどうか」の実験を完了しました。LabEx でさらに多くの実験を行って、スキルを向上させることができます。