Reputation: 2384
I have a function that returns a f64
. I'd like to ensure that the output from this function is used, rather than just ignored. Is there any way to do this?
The return type is not used for error handling so wrapping it in a Result
or Option
doesn't really make sense.
I'd like something similar to this:
#[must_use]
fn calculate_the_thing(number: f64) -> f64 {
number * 2.0
}
Upvotes: 11
Views: 4893
Reputation: 102096
Since Rust 1.27 #[must_use] attribute can be used on functions
#[must_use]
fn calculate_the_thing(number: f64) -> f64 {
number * 2.0
}
fn main() {
calculate_the_thing(4); // warning: unused return value of `calculate_the_thing ` which must be used
let _ = calculate_the_thing(4); // (no warning)
}
In older versions, #[must_use]
only applied to types, not individual values.
One alternative is to define a simple wrapper type that is #[must_use]
:
#[must_use = "this value should be used (extract with .0)"]
pub struct MustUse<T>(pub T);
Your function can then return MustUse<f64>
, and users will get a warning if they write calculate_the_thing(12.3)
, even suggesting the right way to get the thing they want: let x = calculate_the_thing(12.3).0;
. For instance:
fn calculate_the_thing(number: f64) -> MustUse<f64> {
MustUse(number * 2.0)
}
fn main() {
calculate_the_thing(12.3); // whoops
let x = calculate_the_thing(12.3).0;
println!("{}", x);
}
warning: unused `MustUse` which must be used: this value should be used (extract with .0)
--> src/main.rs:9:5
|
9 | calculate_the_thing(12.3); // whoops
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
Upvotes: 20
Reputation: 430851
Yes, you can, thanks to RFC 1940 and available starting in Rust 1.27. Your original code works as-is:
#[must_use]
fn calculate_the_thing(number: f64) -> f64 {
number * 2.0
}
fn main() {
calculate_the_thing(21.0);
}
warning: unused return value of `calculate_the_thing` which must be used
--> src/main.rs:7:5
|
7 | calculate_the_thing(21.0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: #[warn(unused_must_use)] on by default
Finished dev [unoptimized + debuginfo] target(s) in 0.71s
Running `target/debug/playground`
Upvotes: 12