I am learning Rust, and came across the fact that adding an underscore at the beginning of a variable name will make the compiler not warn if it is unused. I am wondering why that feature exists, since unused variables are frowned upon.
Why should I add an underscore prefix to an unused parameter? Very likely just a convention thing. Single unused parameters are often named as just _ , and personally, private members start with underscore. It doesn't look like it has any semantic relevance.
An underscore in front usually indicates an instance variable as opposed to a local variable. It's merely a coding style that can be omitted in favor of "speaking" variable names and small classes that don't do too many things. Follow this answer to receive notifications.
Python automatically stores the value of the last expression in the interpreter to a particular variable called "_." You can also assign these value to another variable if you want.
The underscore in variable names is completely optional. Many programmers use it to differentiate private variables - so instance variables will typically have an underscore prepended to the name. This prevents confusion with local variables. Show activity on this post.
I can see several reasons:
#[must_use]
type, but in your specific case, you know you can safely ignore the value. It is possible to use a _
pattern for that (which is not a variable binding, it's a pattern of its own, but this is probably where the underscore prefix convention comes from), but you might want to document why you ignore the value, or what that value is. This is particularly common in tests in my experience.used_underscore_binding
lint._
for this use-case, as _
is not a variable binding and the value would not be dropped at the end of the enclosing block as with variable binding.Here are some examples as to why you might want the behavior of ignoring an unused variable. Consider _s
in the following function.
fn add_numbers(f: i32, _s: i32) -> i32 { f + 1 }
The _s
variable makes it so we can keep the signature the same even if we haven't implemented it. This also works if we found out we didn't need the _s
but because our library is used in so many different projects we didn't want to change the API to our function. This may or may not be bad practice but could be useful in a situation where _s
needs to stay and not do anything. We could also use _
here but _s
potentially has more meaning as to what the variable is for in the future.
The next place where this can be useful is when a type implements Drop
and you care where that logic happens. In this example you can see that the _result
variable is needed so that the Drop
happens at the end.
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"); } } }
If we use let _result = try_add_numbers(&mut num);
we have a variable that is in scope until the end of main and drop will be called then. If we had used let _ = try_add_numbers(&mut num);
we still don't get a warning but drop is called at the end of the statement. If we use try_add_numbers(&mut num);
without a let binding we get a warning. The output of this program does change depending on which we use with our try_add_numbers function.
It worked 2
or
2 It worked
So there is a use for both _
and _named
variables which need to be chosen based on what the output of your programs needs to be. Play around with my example on the playground to get a feel for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With