Reputation: 2587
I find myself reading large CSV files and collecting the numerical elements into a Vec<&str>
. Thereafter I have to convert them to numeric types and the simplest way I've found to do that is to implement a function like this:
fn to_u32(str: &str) -> u32
{
let str_num: Option<u32> = str.parse();
match str_num
{
Some(num) => num,
None => panic!("Failed to read number"),
}
}
This seems like a fairly common operation so I've sifted through the reference docs but haven't found anything that matches it. Is there a cleaner way to do this?
Upvotes: 1
Views: 137
Reputation: 102256
The Option
type has a large variety of adapter methods which can be used to munge the data around more nicely than repeated match
s.
For example, there's unwrap
and expect
for just extracting the data out of a Some
, panicking if the Option
is None
. The expect
method is actually the closest to your written code: str.parse().expect("Failed to read number.")
.
However, it can often makes sense to use other the functions listed there, to propagate errors, avoiding the hard "crash" of a panic and allowing users (or yourself) to handle errors more centrally and with more control. It also often makes sense to use Result
for this, which gives you the chance to pass along more information in the error case, and also allows one to use the try!
macro, that said, one can easily define an equivalent of try!
for Option
:
macro_rules! option_try {
($e: expr) => {
match $e {
Some(x) => x,
None => return None
}
}
}
Upvotes: 4
Reputation: 128081
Well, you can use unwrap()
to avoid pattern matching, but you should do it sparingly - with unwrap()
you can't handle the actual parse error, so if the string does not represent a number, it'll panic:
let str_num: u32 = str.parse().unwrap();
if let
is also an option:
if let Some(str_num) = str.parse::<u32>() {
// ...
}
You can also use unwrap_or()
if you want to specify some default value:
let str_num: u32 = str.parse().unwrap_or(42);
Or you can use unwrap_or_default()
which employs Default
instance for u32
:
let str_num: u32 = str.parse().unwrap_or_default();
Upvotes: 2