Learn Rust Coding · Урок

Result и оператор ?

Распространение ошибок

Урок 1 из 413 шагов

«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 — преобразование значения Ok
  • map_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 — локальная установка не требуется.

Все уроки этого курса

  1. Result и оператор ?
  2. thiserror
  3. anyhow
  4. Преобразование ошибок
← Назад к Learn Rust Coding