Shanraq.org Shanraq.org
Аргументы запуска: команда и название с пробелами
IT

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

Аргументы запуска: команда и название с пробелами

Урок 35. Передать органайзеру действие и название при запуске из терминала.

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

Предварительно: уроки 4, 14, 22, 26, 30–31 и 34. Если Option и Some забылись, повторите урок 31.

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

В кафе можно сначала подойти к стойке, а потом назвать заказ. Можно также передать записку с заказом сразу при входе. Урок 34 читал строку после запуска; теперь программа получит слова при запуске. Такие слова называют аргументами запуска. Образ ограничен: оболочка терминала сначала разбивает введённую строку на аргументы по своим правилам; Rust получает уже выделенные значения.

Командная строка → cargo run -- → аргументы программы → args()next()Option<String> → действие. Два дефиса -- после cargo run отделяют параметры Cargo от аргументов нашего органайзера. В cargo run -- add "Прочитать Rust" оболочка передаст add и Прочитать Rust как два аргумента: кавычки объединяют слова с пробелом, но не входят в название. Без кавычек название распалось бы на несколько аргументов. std::env::args() последовательно отдаёт значения типа String; первым обычно идёт путь самой программы. .next() берёт следующее значение и возвращает Some(String) или None, если значений больше нет. Каждая новая .next() продвигается дальше. Запись _program означает, что значение сохранено, но намеренно не используется: начальный _ подавляет предупреждение о неиспользуемом имени.

Одна команда при запуске

Сохраните прежний src/main.rs проекта organizer, замените его целиком и сначала выполните cargo run рядом с Cargo.toml. Другие файлы и зависимости не меняются. Без аргументов программа покажет подсказку, приведённую ниже. Затем выполните cargo run -- add "Прочитать Rust": программа покажет Добавить: Прочитать Rust. Последняя строка — планируемое действие; сохранение задачи добавим позже.

Кортеж (command, title, extra) объединяет три результата .next(). Образец (Some(command), Some(title), None) подходит, только если есть команда и название, а лишнего аргумента нет. _ из урока 30 обрабатывает остальные формы. Сравнение command == "add" проверяет знакомое слово команды, а не перевод названия задачи.

fn main() {
    let mut args = std::env::args();
    let _program = args.next();
    let command = args.next();
    let title = args.next();
    let extra = args.next();
    match (command, title, extra) {
        (Some(command), Some(title), None) => {
            if command == "add" {
                println!("Добавить: {title}");
            } else {
                println!("Неизвестная команда: {command}");
            }
        }
        _ => println!("Использование: organizer add \"Название\""),
    }
}
Использование: organizer add "Название"

Для cargo run -- add "Прочитать Rust" программа напечатает Добавить: Прочитать Rust. Здесь add — английское слово «добавить» из урока 2. Имя исполняемого файла в подсказке дано как будущий способ запуска после сборки; при обучении используйте cargo run --. Программа пока не записывает данные и не выполняет другие команды.

Пустое и лишнее

Если после add не указать название, title станет None, и появится подсказка. Если передать лишнее слово без кавычек, extra станет Some(...), и программа тоже покажет подсказку, вместо того чтобы молча потерять часть названия. "" в командной строке может передать пустое название как существующий аргумент; текущий код его не проверяет. Проверку пустого названия добавим при разборе команд. std::env::args() рассчитан на аргументы с корректным Unicode; для иных байтов есть другой способ, который здесь не нужен.

Проверка понимания

  1. Зачем нужны -- в cargo run -- add ...?
  2. Почему args.next() вызывается сначала для _program?
  3. Что изменится, если убрать кавычки вокруг названия с пробелом?

Проверьте: отделить аргументы программы от Cargo; первый аргумент — путь программы; название распадётся и появится лишний аргумент. Восстановите опорную карту.

Задание

Обязательное. Сделайте ту же схему, но при add выводите Запланировано: НАЗВАНИЕ, для неизвестной команды — Команда не найдена, при неполном или лишнем наборе — Нужно: add "Название". Проверьте cargo run -- add "Мой план" и запуск без аргументов. Название должно поступать из args, а не быть готовой строкой в коде.

Граница. Запустите с cargo run -- add Мой план без кавычек и объясните, почему появится подсказка.

Подсказка

Сохраните четыре вызова .next(): путь, команда, название, лишнее слово. В образце с двумя Some и одним None отдельно сравните command с "add".

Эталон после попытки

fn main() {
    let mut args = std::env::args();
    let _program = args.next();
    let command = args.next();
    let title = args.next();
    let extra = args.next();
    match (command, title, extra) {
        (Some(command), Some(title), None) => {
            if command == "add" {
                println!("Запланировано: {title}");
            } else {
                println!("Команда не найдена");
            }
        }
        _ => println!("Нужно: add \"Название\""),
    }
}
Нужно: add "Название"

Блок результата показывает запуск без аргументов; cargo run -- add "Мой план" покажет Запланировано: Мой план. Официальный разбор аргументов и правило cargo run --.

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

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

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

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