Result

Основним механізмом обробки помилок у Rust є перелік Result, який ми коротко розглядали під час обговорення стандартних бібліотечних типів.

use std::fs::File;
use std::io::Read;

fn main() {
    let file: Result<File, std::io::Error> = File::open("diary.txt");
    match file {
        Ok(mut file) => {
            let mut contents = String::new();
            if let Ok(bytes) = file.read_to_string(&mut contents) {
                println!("Дорогий щоденник: {contents} ({bytes} байтів)");
            } else {
                println!("Не вдалося прочитати вміст файлу");
            }
        }
        Err(err) => {
            println!("Щоденник не вдалося відкрити: {err}");
        }
    }
}
This slide should take about 5 minutes.
  • Result має два варіанти: Ok, який містить значення успіху, і Err, який містить деяке значення помилки.

  • Чи може функція спричинити помилку, кодується у сигнатурі типу функції, яка повертає значення Result.

  • Як і у випадку з Option, ви не можете забути обробити помилку: Ви не можете отримати доступ ні до значення успіху, ні до значення помилки без попередньої обробки шаблону на Result, щоб перевірити, який саме варіант ви отримали. Методи на кшталт unwrap полегшують написання швидкого і брудного коду, який не забезпечує надійну обробку помилок, але означає, що ви завжди можете побачити у вихідному коді, де було пропущено належну обробку помилок.

Більше інформації для вивчення

Може бути корисно порівняти обробку помилок у Rust зі стандартами обробки помилок, з якими студенти можуть бути знайомі з інших мов програмування.

Виключення

  • Багато мов використовують виключення, наприклад, C++, Java, Python.

  • У більшості мов з виключеннями інформація про те, чи може функція згенерувати виключення, не відображається у сигнатурі її типу. Це зазвичай означає, що при виклику функції ви не можете визначити, чи може вона згенерувати виключення.

  • Виключення, як правило, розмотують стек викликів, поширюючись вгору, поки не буде досягнуто блоку try. Помилка, що виникла глибоко у стеку викликів, може вплинути на не пов'язану з нею функцію, розташовану вище.

Коди помилок

  • У деяких мовах функції повертають код помилки (або інше значення помилки) окремо від успішного значення, яке повертає функція. Приклади включають C та Go.

  • Залежно від мови можна забути перевірити значення помилки, і в цьому випадку ви можете отримати доступ до неініціалізованого або іншим чином недійсного значення успішного завершення.