Reputation: 2402
#![feature(try_blocks)]
pub fn is_valid(code: &str) -> bool {
let result: Result<bool, ()> = try {
code.chars()
.filter(|x| !x.is_whitespace())
.map(|x| x.to_digit(10).unwrap())
.rev()
.enumerate()
.map(|(i, num)| match i % 2 != 0 {
true => {
let doubled = 2 * num;
match doubled > 9 {
true => doubled - 9,
false => doubled,
}
}
false => num,
})
.sum::<u32>()
% 10
== 0
};
match result {
Ok(value) => value,
Err(_) => false,
}
}
On some inputs, this programme panics, and I don't understand why. The to_digit
returns an Option
, but it is unwrapped, and the None
case should be caught by the try
block. My understanding is that if the .unwrap
is called on a None
value, the try block will return a Result::Error
, which the final match
will convert into false
.
I am new to Rust!
I did try x.to_digit(10).ok_or("Error").unwrap()
to turn it into a Result
rather than an Option
, but it didn't make any difference.
Upvotes: 3
Views: 1163
Reputation: 30577
My understanding is that if the .unwrap is called on a None value, the try block will return a Result::Err
Actually no: from the documentation:
Panics if the self value equals None.
A 'Panic' is very different from returning a Result::Err
. Panics are intended to be used for unrecoverable errors, while returning a Result::Err
is used for everyday potentially recoverable errors. See the error handling chapter in the rust book for more discussion on the differences.
As you had hinted, instead of unwrap
you can use ok_or
to transform the Option
into a Result
:
x.to_digit(10).ok_or("Error")?
Note that I put a '?' on the end, instead of the unwrap
you tried. The effect of the ?
is:
Result::Err
then it is returned from the enclosing function or try blockResult::Ok
then it is unwrapped.It desugars something like this:
match x.to_digit(10).ok_or("Error") {
Err(e) => return Err(e),
Ok(v) => v
}
As mentioned by some in the comments, you may be better off keeping away from unstable features if you are new to rust, although I don't think that is the cause of this issue.
Upvotes: 4