I can't seem to find an elegant way to short-circuit my function when I see an Err.
This way gives me a warning that time_float's initial value is never read.
let mut time_float = 0.0;
if let Ok::<f64, std::num::ParseFloatError>(parsed) = duration_str.trim().parse() {
time_float = parsed; // warning: value assigned to `time_float` is never read
} else {
return Err("Could not parse to float.");
}
This way requires an unreachable return value after the return.
let mut time_float : f64 = match duration_str.trim().parse() {
Ok(x) => x,
Err(_) => {
return Err("Could not parse to float.");
0.0 // warning: unreachable expression
}
};
I thought it went without saying that the compiler wouldn't allow it, so I didn't say it!
58 | time_float = result
| ^^^^^^ expected floating-point variable, found enum `std::result::Result`
|
= note: expected type `{float}`
= note: found type `std::result::Result<_, _>`
Then clearly your example is different from your actual code.
let time_float;
if let Ok::<f64, std::num::ParseFloatError>(parsed) = duration_str.trim().parse() {
time_float = parsed;
} else {
return Err("Could not parse to float.");
}
let time_float : f64 = match duration_str.trim().parse() {
Ok(x) => x,
Err(_) => {
return Err("Could not parse to float.");
}
};
I'm sorry, I don't follow. I've been copy-and-pasting from my code. You're welcome to take a look. It's this file in this commit.
Ah, now I see. I had had some other experimental code uncommented when I tried uncommenting the 0.0 line, and I pasted an unrelated error in without realizing it. You obviously caught it, though.
This works without error, though I could have sworn that it didn't when I wrote it initially, and later when I tried the same thing in other code:
let mut time_float : f64 = match duration_str.trim().parse() {
Ok(x) => x,
Err(_) => {
return Err("Could not parse to float.");
//0.0
}
};
@dtolnay Thanks for your error-chain suggestion. At the moment, I'm trying to stick to the standard library as much as possible so I can thoroughly learn any needed boilerplate. It's good to know about error-chain for the future, though!
let mut time_float = duration_str.trim().parse::<f64>().or(Err("Could not parse to float."))?;
I also gather from @dtolnay's information that if I implement the std::num::ParseFloatError trait either using a helper crate, or just manually, then I could even do this. Though I'm unclear as to whether I would be able to customize my Err in this case.
let mut time_float = duration_str.trim().parse::<f64>()?;
// or, I think equivalently
let mut time_float : f64 = duration_str.trim().parse()?;
You may have more luck looking up information about the try! macro, which was around in rust a long time before ? supplanted it.
To my understanding, x? right now behaves pretty much exactly as try!(x) used to.
(Technically speaking,? is supposed to be more general than try!() thanks to the new Carrier trait, whereas try! was strictly for Result. However, Result is currently the only type that implements Carrier.)