XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
До появления ?, аналогичная функциональность была доступна через макрос try!. Сейчас рекомендуется использовать оператор ?, но вы до сих пор можете найти try!, когда просматриваете старый код. Функция multiply из предыдущего примера с использованием try! будет выглядеть следующим образом:
// Для компиляции и запуска с помощью Cargo этого примера без ошибок
// поменяйте в `Cargo.toml` значение поля `edition` секции
// `[package]` на "2015".
use std::num::ParseIntError;
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
let first_number = try!(first_number_str.parse::<i32>());
let second_number = try!(second_number_str.parse::<i32>());
Ok(first_number * second_number)
}
fn print(result: Result<i32, ParseIntError>) {
match result {
Ok(n) => println!("n равно {}", n),
Err(e) => println!("Ошибка: {}", e),
}
}
fn main() {
print(multiply("10", "2"));
print(multiply("t", "2"));
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1
Посмотрите главу "Другие способы использования ?" для большей информации.
Предыдущие примеры всегда были очень удобны: Result взаимодействовали с другими Result, а Option - с другими Option.
Иногда Option необходимо взаимодействовать с Result, или Result<T, Error1> с Result<T, Error2>. В этих случаях, нам нужно управлять этими разными типами ошибок таким образом, чтобы можно было их компоновать и легко взаимодействовать с ними.
В следующем коде, два варианта unwrap генерируют разные типы ошибок. Vec::first возвращает Option, в то время как parse::<i32> возвращает Result<i32, ParseIntError>:
fn double_first(vec: Vec<&str>) -> i32 {
let first = vec.first().unwrap(); // Генерирует ошибку 1
2 * first.parse::<i32>().unwrap() // Генерирует ошибку 2
}
fn main() {
let numbers = vec!["42", "93", "18"];
let empty = vec![];
let strings = vec!["tofu", "93", "18"];
println!("Первое удвоенное {}", double_first(numbers));
println!("Первое удвоенное {}", double_first(empty));
// Ошибка 1: входной вектор пустой
println!("Первое удвоенное {}", double_first(strings));
// Ошибка 2: элемент не может быть преобразован в число
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
В следующих главах мы рассмотрим различные стратегии обработки этих типов проблем.
Наиболее простой способ обработки ошибок разных типов - это встраивание их друг в друга.
use std::num::ParseIntError;
fn double_first(vec: Vec<&str>) -> Option<Result<i32, ParseIntError>> {
vec.first().map(|first| {
first.parse::<i32>().map(|n| 2 * n)
})
}
fn main() {
let numbers = vec!["42", "93", "18"];
let empty = vec![];
let strings = vec!["tofu", "93", "18"];
println!("Первое удвоенное: {:?}", double_first(numbers));
println!("Первое удвоенное: {:?}", double_first(empty));
// Ошибка первая: исходный вектор пустой
println!("Первое удвоенное {:?}", double_first(strings));
// Ошибка вторая: элемент не переводится в число
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה