fn lines_from_file<F>(filename: F) -> Result<io::Lines<BufReader<File>>, io::Error>
where
F: std::convert::AsRef<std::path::Path>,
{
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
fn main() {
let filename: &str = "input.pdl";
// This works fine
match lines_from_file(filename) {
Ok(lines) => {
for line in lines {
println!("{:?}", line);
},
}
Err(e) => println!("Error {:?}", e),
}
}
I'd like to use this instead:
if let lines = Ok(lines_from_file(filename)) {
for line in lines {
println!("{:?}", line);
}
} else {
println!("Error {:?}" /*what goes here?*/,)
}
But that gives an error:
| if let lines = Ok(lines_from_file(filename)) {
| ^^ cannot infer type for `E`
What is the idiomatic way of using an if-let binding when matching a Result
and still being able to capture the error?
The if let expression in rust allows you to match an expression to a specific pattern. This is different from the if expression that runs when a condition is true. Using the let keyword, you can specify a pattern that is compared against the specified expression.
It is an enum with the variants, Ok(T) , representing success and containing a value, and Err(E) , representing error and containing an error value. Functions return Result whenever errors are expected and recoverable.
To “unwrap” something in Rust is to say, “Give me the result of the computation, and if there was an error, panic and stop the program.” It would be better if we showed the code for unwrapping because it is so simple, but to do that, we will first need to explore the Option and Result types.
[...] using an if-let binding when matching a Result and still being able to capture the error?
This is fundamentally impossible with one if let
. The if let
construct's only purpose is to make life easier in the case where you only want to destructure one pattern. If you want to destructure both cases of a Result
, you have to use match
(or multiple if let
or unwrap()
, but this is not a good solution). Why you don't want to use match
in the first place?
Regarding your compiler error: you added the Ok()
on the wrong side:
if let Ok(lines) = lines_from_file(filename) { ... }
This is the correct way of using if let
: the destructuring pattern to the left, the expression producing a value to the right.
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