Reputation: 7075
I'm writing a program that subsets an incoming file into either one or two output files depending on a CLI flag.
Minimally it works like so:
use std::{fs::File, io::Write};
fn main() {
// Would be a CLI flag
let write_all = true;
let mut evens = File::create("evens.txt").expect("Nuh-uh");
let mut odds: File;
if write_all {
odds = File::create("odds.txt").expect("Nuh-uh");
}
for i in 1..5 {
if i % 2 == 0 {
write!(&mut evens, "{}\n", i).expect("Can't write");
} else {
if write_all {
write!(&mut odds, "{}\n", i).expect("Can't write");
}
}
}
}
This won't compile due to odds
being potentially uninitialised/out of scope as it's created in a conditional.
error[E0381]: borrow of possibly-uninitialized variable: `odds`
--> src/main.rs:17:24
|
17 | write!(&mut odds, "{}\n", i).expect("Can't write");
| ^^^^^^^^^ use of possibly-uninitialized `odds`
error: aborting due to previous error
I've seen this answer about using Option<File>
, but cannot see how to apply it to my problem.
Another alternative I've considered is just creating the odds.txt
file and removing it at the end if !write_all
is true, but I don't like this solution.
Upvotes: 0
Views: 512
Reputation: 7075
Using Option<File>
you need to set Some(File)
or None
. Then to use File
you need to unwrap the &mut Option<File>
to Option<&mut File>
, which can be done using as_mut
or by matching odds
.
use std::{fs::File, io::Write};
fn main() {
// Would be a CLI flag
let write_all = true;
let mut evens = File::create("evens.txt").expect("Nuh-uh");
let mut odds: Option<File>;
if write_all {
odds = Some(File::create("odds.txt").expect("Nuh-uh"));
} else {
odds = None;
}
for i in 1..5 {
if i % 2 == 0 {
write!(&mut evens, "{}\n", i).expect("Can't write");
} else {
if write_all {
// let mut file = odds.as_mut().unwrap();
// write!(&mut file, "{}\n", i).expect("Can't write");
match odds {
Some(ref mut file) => write!(file, "{}\n", i).expect("Can't write"),
None => panic!("No file?"),
}
}
}
}
}
Upvotes: 2