Становится проще, если тип возвращаемого значения не i32
, а Result<i32, SomeErrorType>
.
В этом случае вы можете использовать знак вопроса, чтобы получить что-то вроде этого:
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, i32> {
let first_number = first_number_str.parse::<i32>().map_err(|_| -1)?;
let second_number = second_number_str.parse::<i32>().map_err(|_| -2)?;
Ok(first_number * second_number)
}
fn main () {
assert_eq!(Ok(2), multiply("1", "2"));
assert_eq!(Err(-1), multiply("a", "2"));
assert_eq!(Err(-2), multiply("1", "b"));
assert_eq!(Err(-1), multiply("a", "b"));
}
Если бы я делал это, я бы, вероятно, go с этим кодом. Излишне говорить, что я бы не использовал Result<i32, i32>
, а вместо Result<i32, CustomErrorTypeDenotingIfProblemIsAOrB>
. Возможно, я бы даже сохранил тип ошибки parse
, пропустив map_err
.
Вот информация об операторе вопросительного знака.
Если вы настаиваете на сохраняя в качестве возвращаемого значения i32
, Result
предлагает множество различных методов, которые могут помочь достичь чего-то похожего на вашу цель. Тем не менее, я не знаю ни одного, канонического способа сделать это, поэтому я мог бы взглянуть на and_then
, map_err
и др.
Редактировать: Я просто понял, что это на самом деле предлагается в следующей главе .