Result и оператор ?
Распространение ошибок
«Result и оператор ?» — бесплатный урок Learn Rust Coding на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Learn Rust Coding, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Learn Rust Coding содержит 4 уроков всего.
Тип Result
Result<T, E> представляет операцию, которая может завершиться успешно с результатом Ok(T) или завершиться ошибкой Err(E). Это основной тип Rust для обработки ошибок.
fn main() {
let parsed: Result<i32, _> = "42".parse::<i32>();
println!("{:?}", parsed);
}Сопоставление с Result
Вы можете явно обработать оба варианта с помощью match.
fn main() {
match "oops".parse::<i32>() {
Ok(n) => println!("got {n}"),
Err(e) => println!("error: {e}"),
}
}Возврат Result
Функции, которые могут завершиться ошибкой, возвращают Result, позволяя вызывающему коду решить, как обрабатывать ошибки.
fn halve(n: i32) -> Result<i32, String> {
if n % 2 == 0 {
Ok(n / 2)
} else {
Err("odd number".to_string())
}
}
fn main() {
println!("{:?}", halve(10));
println!("{:?}", halve(7));
}Оператор ?
Оператор ? извлекает значение Ok или досрочно возвращает Err из функции. Он заменяет многословный код с сопоставлением и возвратом.
fn double_str(s: &str) -> Result<i32, std::num::ParseIntError> {
let n = s.parse::<i32>()?;
Ok(n * 2)
}
fn main() {
println!("{:?}", double_str("21"));
println!("{:?}", double_str("x"));
}Цепочки с ?
Несколько потенциально ошибочных шагов выглядят наглядно, если объединить их с помощью ?; первая ошибка прерывает выполнение остальных.
fn sum_two(a: &str, b: &str) -> Result<i32, std::num::ParseIntError> {
let x = a.parse::<i32>()?;
let y = b.parse::<i32>()?;
Ok(x + y)
}
fn main() {
println!("{:?}", sum_two("3", "4"));
}? в main
main может возвращать Result, поэтому оператор ? работает и там. Возвращённый Err завершает программу с ненулевым кодом выхода.
fn main() -> Result<(), std::num::ParseIntError> {
let n: i32 = "100".parse()?;
println!("parsed {n}");
Ok(())
}Полезные методы Result
Полезные комбинаторы:
unwrap_or(default)— значение или запасной вариантmap— преобразование значения Okmap_err— преобразование ошибкиis_ok/is_err— проверка варианта
fn main() {
let n = "x".parse::<i32>().unwrap_or(-1);
println!("{n}");
}Преобразование Option в Result
Преобразуйте Option в Result с помощью ok_or, чтобы ? мог передать содержательную ошибку дальше.
fn first_char(s: &str) -> Result<char, String> {
let c = s.chars().next().ok_or("empty string".to_string())?;
Ok(c)
}
fn main() {
println!("{:?}", first_char("hi"));
println!("{:?}", first_char(""));
}Как ? преобразует ошибки
Если типы ошибок различаются, ? вызывает From::from, чтобы преобразовать ошибку в объявленный для функции тип ошибки. Благодаря этому обработка ошибок между уровнями остаётся удобной.
Избегайте unwrap в рабочем коде
unwrap и expect вызывают аварийное завершение при Err. Они подходят для примеров и тестов, но в настоящем коде предпочитайте ? или явную обработку, чтобы ошибки можно было восстановить.
Цепочки с and_then
and_then запускает следующий потенциально ошибочный шаг только в случае успеха предыдущего, передавая ему значение.
fn main() {
let result = "8"
.parse::<i32>()
.and_then(|n| Ok(n * 2));
println!("{:?}", result);
}Быстрая проверка
Что делает оператор ?, применённый к Result со значением Err?
Итоги
Вы изучили обработку ошибок на основе Result:
Result<T, E>представляет успех или ошибку?извлекает Ok или досрочно возвращает Err?работает в функциях иmain, возвращающих Result- Комбинаторы, такие как
map,map_err,unwrap_orиok_or, упрощают работу - Избегайте
unwrapв рабочем коде
Изучай Rust с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 39
- Уроки
- 144
Часто задаваемые вопросы
Урок «Result и оператор ?» бесплатный?
Да — полный текст урока «Result и оператор ?» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Learn Rust Coding, подпишись на CoddyKit PRO. Курс Learn Rust Coding содержит 4 уроков всего.
Чему я научусь в уроке «Result и оператор ?»?
Распространение ошибок Ты практикуешь Learn Rust Coding с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Learn Rust Coding?
Предыдущий опыт не требуется. Learn Rust Coding на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Result и оператор ?»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Learn Rust Coding?
Да. Каждый урок Learn Rust Coding включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Result и оператор ?
- thiserror
- anyhow
- Преобразование ошибок