Why does Rust still consider the file to be of type Result
even after I've handled the error in the main function?
use std::{fs::File, io};
fn get_file(file_name: &str) -> Result<File, io::Error> {
let file = File::open(file_name);
let file_err = match file {
Ok(file) => return Ok(file),
Err(err) => err,
};
match file_err.kind() {
io::ErrorKind::NotFound => File::create(file_name),
_ => Err(file_err),
}
}
fn main() {
let file = get_file("random.txt");
if let Err(err) = file {
println!("Error: {}", err);
return;
}
// Result<File, Error>
println!("file {:?}", file);
}
You extracted the error from the Result and dealt with it, but you didn't extract the file from the Result. One way to do it is:
let file = match file {
Ok(f) = f,
Err(err) => {
println!("Error: {}", err);
return;
}
};
// now `file` is type File
Or perhaps this is better:
let file = match get_file("random.txt") {
Ok(f) = f,
Err(err) => {
println!("Error: {}", err);
return;
}
};
5 Likes
It looks like you expect Rust to have flow-sensitive typing. It doesn't (and enum variants are not types – enums are sum types, not unions of types).
1 Like
kornel
July 2, 2024, 12:01pm
4
Rust doesn't do type analysis like TypeScript or new instanceof in Java.
Type of a variable stays the same, even if you checked what is in it.
Result/Err is not special in Rust. It's just an enum, like enum R { A, B, C }
, so if you checked that variable == R::A
, it wouldn't change it to be R::B
.
You need to pattern match on Result::Ok to get the non-error value, or use ? (Try) operator that does this match itself.
4 Likes
system
Closed
September 30, 2024, 12:01pm
5
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.