Problem:
When I try to run code with the following function:
fn invalid_function() {
let mut file = File::open("data/AA.csv")?;
}
This returns the following error:
$ cargo run
Compiling voxide v0.1.0 (/rick/follinge-2020-08-10/projects/voxide)
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> src/main.rs:10:45
|
9 | fn invalid_function() {
| --------------------- this function should return `Result` or `Option` to accept `?`
10 | let mut file = File::open("data/AA.csv")?;
| ^ cannot use the `?` operator in a function that returns `()`
|
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `voxide` due to previous error
The 1st clue is in asking ourselves what does the question mark do in this context? The answer is error propagation:
https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html
So basically it worked in main() because that was the top level function, and if we failed, we crashed as the error state was uncaught which is okay.
But if we use the question mark operator in a function, we need to return the Result which tells the caller that they need to handle a potential error state.
A better way to handle it is to either use the if or match keywords.
fn valid_function() -> () {
if let Ok(file) = File::open("data/AA.csv") {
// Do something with the file
}
else {
// Handle the error
}
}
This will open a file, and check for errors.
This pattern is used so often that Rust has a match keyword for dealing with enums:
fn better_valid_function() -> () {
let file_result = File::open("data/AA.csv");
let file = match file_result {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html
Top comments (0)