Shanraq.org Shanraq.org
Удобные команды
IT

Rust: с нуля до своего органайзера Урок 54 из 60

Удобные команды

Урок 54. Давать понятную справку и различать обычный ответ программы и ошибку.

Текст переведён с помощью ИИ.

Повторите аргументы запуска и разбор команд. Здесь показана маленькая оболочка органайзера без постоянных данных.

Образ и опорная карта

У кассы есть очередь за услугой и отдельное окно для проблем. В терминале stdout — поток обычного результата, stderr — поток сообщений об ошибках. Код завершения сообщает другой программе, удалось ли действие: 0 означает успех, здесь 2 означает неверную команду. Карта: аргументы → выбор команды → stdout или stderr → код завершения. Образ не гарантирует, что текст на экране всегда приходит в порядке двух потоков.

std::env::args() даёт слова запуска: первое слово — путь программы; skip(1) пропускает его, collect() собирает оставшиеся слова в Vec<String>. args.first() может вернуть отсутствие слова, поэтому результат преобразуется через map. as_str() даёт представление строки для сопоставления. В match | означает «любой из перечисленных вариантов», а if args.len() <= 1 — дополнительное условие. println! пишет в stdout, eprintln! — в stderr. std::process::exit(code) сообщает ненулевой код системе.

Запустите и разберите

Создайте пустой проект Cargo, вставьте первый Rust блок в src/main.rs. cargo run -- help передаёт программе help: два знака -- заканчивают аргументы Cargo. cargo run -- list выводит пустой список. cargo run -- mystery сообщает ошибку; её код 2 относится к запущенной программе. Первый вывод ниже получается от запуска без аргументов. Чтобы проверить именно код программы без влияния Cargo, выполните собранный файл из target/debug/organizer с неизвестным словом и проверьте код средствами своей оболочки.

fn run(args: &[String]) -> i32 {
    match args.first().map(|word| word.as_str()) {
        None | Some("help") | Some("--help") if args.len() <= 1 => {
            println!("Команды: help, list");
            0
        }
        Some("list") if args.len() == 1 => {
            println!("Задач пока нет");
            0
        }
        _ => {
            eprintln!("Неизвестная команда");
            2
        }
    }
}

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    let code = run(&args);
    if code != 0 {
        std::process::exit(code);
    }
}
Команды: help, list

Вопросы для воспроизведения

  1. Почему первое слово args() пропускают?
  2. Куда попадёт сообщение о неизвестной команде?
  3. Зачем сценариям код завершения?

Задание

Обязательное. Добавьте команду status без дополнительных слов: она должна вывести число задач 0 и вернуть код 0. Включите status в справку. Убедитесь, что status extra остаётся ошибкой с кодом 2.

Ответы

Показать ответы

Сделайте отдельную ветвь Some("status") if args.len() == 1 перед ветвью _. Обновите строку справки, но не меняйте ветвь ошибок.

fn run(args: &[String]) -> i32 {
    match args.first().map(|word| word.as_str()) {
        None | Some("help") | Some("--help") if args.len() <= 1 => {
            println!("Команды: help, list, status");
            0
        }
        Some("list") if args.len() == 1 => {
            println!("Задач пока нет");
            0
        }
        Some("status") if args.len() == 1 => {
            println!("Задач: 0");
            0
        }
        _ => {
            eprintln!("Неизвестная команда");
            2
        }
    }
}

fn main() {
    let args: Vec<String> = std::env::args().skip(1).collect();
    let code = run(&args);
    if code != 0 {
        std::process::exit(code);
    }
}
Команды: help, list, status

После проверки

Потоки и код завершения важны при вызове органайзера из сценариев. При настоящем сохранении ошибка файла должна идти через stderr и ненулевой код. Вернитесь к уроку 36. Документация args.

Предыдущий урок · Оглавление

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Комментарии (0)

Пока нет комментариев. Будьте первым.