私はRustを学んでいて、変数名の先頭にアンダースコアを追加すると、コンパイラーが未使用の場合に警告を出さなくなるという事実に遭遇しました。未使用の変数が嫌われるので、なぜその機能が存在するのかと思います。
いくつかの理由がわかります。
#[must_use]
型を返す関数を呼び出していますが、特定のケースでは、値を無視しても安全です。そのために_
パターンを使用することは可能です(これは変数バインディングではなく、独自のパターンですが、これがおそらくアンダースコアプレフィックスの規則の元になる場所です)。値、またはその値が何であるかを無視します。これは、私の経験のテストで特に一般的です。used_underscore_binding
lintによって強制されます。_
は変数バインディングではなく、値はステートメントの最後で削除されるため、この使用例では単に_
を使用することはできません。未使用の変数を無視する動作が必要な理由の例をいくつか示します。次の関数で__s
_を検討してください。
_fn add_numbers(f: i32, _s: i32) -> i32 {
f + 1
}
_
__s
_変数を使用すると、実装していなくても署名を同じに保つことができます。これは、__s
_が必要ないことがわかった場合にも機能しますが、ライブラリが非常に多くの異なるプロジェクトで使用されているため、APIを関数に変更したくありませんでした。これは悪い習慣かもしれませんし、そうでないかもしれませんが、__s
_がとどまり、何もしない必要がある状況で役立ちます。ここで__
_を使用することもできますが、__s
_は、将来の変数の目的に関してより多くの意味を持つ可能性があります。
これが役立つ次の場所は、型がDrop
を実装し、そのロジックがどこで発生するかを気にする場合です。この例では、Drop
が最後に発生するように__result
_変数が必要であることがわかります。
_fn main() {
let mut num = 1;
// let _ = try_add_numbers(&mut num); // Drop is called here for _
let _result = try_add_numbers(&mut num); // without the _result we have a warning.
println!("{}", num);
// Drop is called here for the _result
}
// keep the api the same even if an aurgument isn't needed anymore or
// has not been used yet.
fn add_numbers(f: i32, _s: i32) -> i32 {
f + 1
}
// This function returns a result
fn try_add_numbers(i: &mut i32) -> Result<GoodResult, GoodResult> {
if *i > 3 {
return Err(GoodResult(false));
}
*i = add_numbers(*i, 0);
Ok(GoodResult(true))
}
struct GoodResult(bool);
impl Drop for GoodResult {
fn drop(&mut self) {
let &mut GoodResult(result) = self;
if result {
println!("It worked");
} else {
println!("It failed");
}
}
}
_
let _result = try_add_numbers(&mut num);
を使用する場合、mainの最後までドロップされ、その後呼び出される変数が存在します。 let _ = try_add_numbers(&mut num);
を使用した場合でも、警告は表示されませんが、ステートメントの最後でdropが呼び出されます。 letバインディングなしでtry_add_numbers(&mut num);
を使用すると、警告が表示されます。このプログラムの出力は、try_add_numbers関数で使用する内容によって異なります。
_It worked
2
_
または
_2
It worked
_
したがって、__
_変数と__named
_変数の両方を使用する必要があります。これらの変数は、プログラムの出力が何である必要があるかに基づいて選択する必要があります。 playground で私の例を試して、感じをつかんでください。
一致変数に関連するこの警告を調べている間、私はここでGoogleを見つけました。これは接線的に関連しています。
Result
を取得するコードがあり、大文字と小文字を区別したい場合がありますが、エラー値は気にしません。 _e
などを使用する代わりに、明示的にバインドしない_
を実際に使用できます。具体的な例を示します。エラーを返すので、エラーの値は気にしません。
fn some_method() -> Result<u32, MyCustomError> {
// ...
let id: u32 = match some_str.parse() {
Ok(value) => value,
Err(_) => return Err(MyCustomError::Blah)
}
// ...
}