Главная / Курсы / Rust / Функция main()
# Глава 6. Функция main() Точкой входа (entry point) программы на Rust является функция `main()`. Эта функция не имеет параметров и, как правило, не имеет возвращаемого значения: ```rust {.example_for_playground .example_for_playground_001} fn main() { println!("This is the simplest Rust program."); } ``` Для сравнения небольшая программа _hello_ на языке C: ```c #include <stdio.h> int main(int argc, char* argv[]) { if (argc < 2) { printf( "The necessary argument is missing.\n" "Please run '%s <name>'\n", argv[0]); return 1; } printf("Hello %s!\n", argv[1]); return 0; } ``` Программа _hello_ печатает приветствие, используя первый аргумент командной строки в качестве имени. Вызов `./hello human` выведет в консоль `Hello human!`, и при завершении программа вернет 0. Программа, вызванная без аргументов, напечатает сообщение об ошибке с подсказкой и завершится с кодом 1: ``` The necessary argument is missing. Please run './hello <name>' ``` ## Получение аргументов командной строки в Rust В программе на C аргументы командной строки передаются прямо в `main()`. В Rust аргументы командной строки в программу передаются иначе. Для получения аргументов можно воспользоваться модулем [std::env](https://doc.rust-lang.org/std/env) из стандартной библиотеки: ```rust {.example_for_playground .example_for_playground_002} use std::env; fn main() { let argv: Vec<String> = env::args().collect(); println!("The program path and name: '{}'.", argv[0]); let argc = argv.len(); println!("The program got {} arguments:", argc - 1); for i in 1..argc { println!("{:>4} - {:?}", i, argv[i]); } } ``` Функция `env::args()` возвращает итератор по аргументам процесса, а `collect()` преобразует итератор в коллекцию. В данном случае это массив строк, первым элементом которого является имя исполняемого файла. Вызов программы с аргументами `./show_args first 2 "t h i r d"` напечатает: ``` The program path and name: './show_args'. The program got 3 arguments: 1 - "first" 2 - "2" 3 - "t h i r d" ``` Для более удобной работы с аргументами командной строки есть крейт [clap](https://docs.rs/clap/latest/clap/). О крейтах и их использовании будет рассказано в другой главе. ## Возвращение результата работы программы Для возврата результатов в модуле [std::result](https://doc.rust-lang.org/std/result/) стандартной библиотеки определен специальный тип: ```rust enum Result<T, E> { Ok(T), Err(E), } ``` Это перечисление с двумя вариантами `Ok` и `Err`. Типы `T` и `E` являются обобщенными параметрами перечисления `Result<T, E>`. Обобщенные типы и перечисления будут рассмотрены в следующих главах. Сейчас важно запомнить, что в случае успеха внутри варианта `Ok` находится значение типа `T`. При неудаче внутри варианта `Err` находится ошибка типа `E`. Для функции `main()` в качестве типа `T` логично использовать единичный тип `()`. Для обозначения ошибок можно использовать целый тип, строку, перечисление и другое. В программе _hello_, переписанной с C на Rust, в качестве возвращаемого типа `main()` используется `Result<(), ErrorCode>`. Здесь `ErrorCode` — небольшое перечисление с одним вариантом ошибки: `MissingArgument`. ```rust #[derive(Debug)] enum ErrorCode { MissingArgument } fn main() -> Result<(), ErrorCode> { let argv: Vec<String> = env::args().collect(); if argv.len() < 2 { println!( "The necessary argument is missing.\n\ Please run '{} <name>'", argv[0]); return Err(ErrorCode::MissingArgument); } println!("Hello {}!", argv[1]); Ok(()) } ``` Пояснение к коду: - Инструкция `#[derive(Debug)]` является атрибутом перечисления `ErrorCode`. А ее часть `derive(Debug)` сообщает компилятору о необходимости автогенерации подходящей реализации типажа `Debug`. Этот типаж отвечает за отображение значений типа при форматировании строки, например в макросе `println!()`. - Выражение `Err(ErrorCode::MissingArgument)` создает вариант перечисления `Err` с ошибкой `MissingArgument`. - Выражение `Ok(())` формирует вариант `Ok` с пустым кортежем внутри. Поведение программы на Rust идентично версии, написанной на C. Немного отличается вывод программы, вызванный без аргументов. Помимо сообщения будет напечатано наименование ошибки: ``` The necessary argument is missing. Please run './hello <name>' Error: MissingArgument ``` Имеется альтернативный способ вернуть код из `main()` при завершении программы. В модуле [std::process](https://doc.rust-lang.org/stable/std/process/) реализована функция: ```rust fn exit(code: i32) -> ! ``` Эта функция не возвращает управление вызывающему коду, так как незамедлительно завершает процесс. Код завершения `code` передается в ОС. Следует учитывать, что поскольку эта функция завершает процесс, никакие деструкторы не будут вызваны. Если требуется чистое завершение работы, следует вызывать эту функцию только в той точке, где больше не осталось неосвобожденных ресурсов. Либо вовсе не использовать функцию `exit()`, возвращая из `main()` результат, как показано в примере программы _hello_. ## Заключение - Точкой входа программы на Rust является функция `main()`. - Функция `main()` не имеет входных параметров, но может возвращать значение. - Получить аргументы командной строки можно с помощью модуля `std::env`. - В качестве возвращаемого значения `main()` следует использовать перечисление `Result<>`. - В случае успеха `Result<>` будет содержать пустой кортеж `()`. - Для обозначения ошибки в `Result<>` можно использовать: целое, строку или перечисление.
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!