Это не всегда очевидно, однако язык программирования Rust в основном акцентируется на расширении возможностей: независимо от того, какой код сейчас вы пишете, Rust дает вам средства идти дальше, чтобы программировать в более широком спектре доменов, чем вы делали это ранее.
Примечание: здесь приведен перевод книги "The Rust Programming Language" [1].
Возьмём для примера работу "на системном уровне", где акцент делается на низкоуровневых деталях управления памятью, представлению данных, параллелизме выполнения кода. Традиционно эта область программирования рассматривалась как тайная магия, доступная только избранным, которые посвятили многие годы обучению, чтобы избежать многих печально известных ловушек и проблем. И даже специалисты в этой области стараются писать свой код с максимальной осторожностью, чтобы не создавать открытых дыр для создания эксплойтов, возможностей краха или повреждения кода.
Rust разрушает эти барьеры, устраняя старые проблемы, и предоставляя дружелюбный, тщательно отлаженный набор инструментов, которые помогут вам на своем пути. Программисты, которым нужно "полезть внутрь" для низкоуровневого управления поведением программы, могут это делать вместе с Rust, не беря на себя обычный риск сбоев или дыр в безопасности, и без необходимости изучать непостоянные тонкости работы тучлейнов в разных рабочих средах. И что еще лучше, Rust разработан таким образом, чтобы направлять вас в сторону написания надежного кода, который в том числе будет эффективным в контексте скорости и использования памяти.
Программисты, кто уже сейчас сосредоточился на низкоуровневом коде, с помощью Rust могут вполне удовлетворить свои запросы. Например, введение параллелизма в Rust это относительно безопасная операция: компилятор поймает и укажет классические ошибки. И вы можете заняться более агрессивными оптимизациями в своем коде с уверенностью, что не будете случайно вводить сбои или уязвимости.
Но Rust не ограничивается низкоуровневым системным программированием. Он достаточно выразителен и эргономичен, чтобы создать консольные (CLI) приложения, веб-серверы и многое другое в довольно приятной манере написания кода - в этой книге вы найдете простые примеры решения различных задач. Работая с Rust, вы легко перенесете свой опыт с одного домена на другой; например, вы сможете выучить Rust, написав web-приложение, и потом сделать аналогичную работу на вашем Raspberry Pi.
— Nicholas Matsakis и Aaron Turon
Rust предлагает следующие полезные инструменты для программирования:
• Cargo, менеджер зависимостей и система сборки. Она снимает головную боль по добавлению, компиляции зависимостями и управлению ими по всему спектру экосистемы Rust. • Rustfmt, утилита форматирования, помогающая привести к единообразию стиль кодирования разных разработчиков. • Rust-analyzer добавляет интеграцию в систему разработки (Integrated Development Environment, IDE) функцию автозавершения кода и встроенной индикации ошибок.
Для кого эта книга. Подразумевается, что вы уже программируете на другом языке программирования, причем не делается никаких предположений, на каком именно. Авторы постарались сделать материал широко доступным для людей из самых разных областей программирования. Здесь никто не тратит время на пространные объяснения, что такое программирование вообще или как об этом думать. Если вы абсолютный новичок в программировании, то вероятно лучше сначала прочитать какую-нибудь книгу, которая специально акцентируется на введении в программирование.
Как использовать эту книгу. Изложение книги рассчитано на то, что вы читаете её от начала и до конца. Последующие главы построены на концепциях предыдущих глав, и более ранние главы не могут сразу погружаться в подробности каких-то моментов, которые будут описаны в будущем.
В этой книге вы найдете 2 разновидности глав: главы концепции и главы проектов. В главах концепций вы научитесь различным аспектам языка Rust. В главах проектов будут рассмотрены сборки небольших программ, что закрепит только что изученную теорию. Главы 2, 12, и 20 это как раз главы проектов; остальное это главы концепций.
Глава 1, знакомство. В главе 1 объясняется, как установить Rust, как написать простейшее приложение "Hello, world!", и как использовать Cargo, менеджер пакетов и утилиту сборки. В этой статье приведен перевод главы 1.
Глава 2, базовые понятия. Это практическое введение в написание программ на Rust на примере игры с угадыванием чисел. Здесь мы рассмотрим концепции на высоком уровне, а более поздние главы предоставят дополнительную информацию. Если вы хотите сразу же "испачкать руки", то глава 2 это как раз то место.
Глава 3, функционал. Здесь приведено описание конструкций языка Rust, аналоги которых можно найти в других языках программирования.
Глава 4, система владения. Эта глава научит вас системе владения (Rust ownership system). Если вы дотошный ученик, который любит разобраться во всех деталях, то можете пропустить главу 2 и перейти к главе 3, с последующим возвратом к главе 2, когда вы хотите работать над проектом, применяя изученные детали.
Глава 5, типы. Здесь обсуждаются структуры и методы.
Глава 6, управление вычислениями. Здесь показаны перечисления, математические выражения и конструкции управления потоком вычислений. Вы научитесь использовать структуры и перечисления для создания собственных типов в Rust.
Глава 7, организация кода. Вы изучите систему модулей Rust, познакомитесь с правилами приватности для организации вашего кода, а также с библиотечным интерфейсом программирования (Application Programming Interface, API).
Глава 8, библиотеки. Здесь обсуждаются часто используемые структуры данных стандартной библиотеки, такие как векторы, строки, хэш-карты.
Глава 10, generics, traits, lifetimes. Погружение в термины generics, traits и lifetimes, что дает вам возможность определять код, который будет применяться для нескольких типов.
Глава 11, тестирование. Здесь рассказывается все от тестировании, которое даже с гарантиями безопасности Rust необходимо выполнить, чтобы добиться корректной работы вашей программы.
Глава 12, реальный пример программы. Для примера будет рассмотрена реализация частичной функциональности утилиты командной строки grep для поиска текста по файлам. Здесь закрепляется все то, чему научились в предыдущих главах.
Глава 13, замыкания и итераторы. Показываются замыкания (closures) и итераторы (iterators): фичи Rust, которые унаследованы от функциональных языков программирования.
Глава 14, Cargo. Будет более глубоко рассмотрены лучшие практики использования Cargo, и поговорим про совместное использование библиотек между различными участниками разработки.
Глава 15, умные указатели. Здесь рассматриваются smart pointers, предоставляемые стандартной библиотекой, а также характерные черты, разрешающие их функциональность.
Глава 16, потоки. Рассмотрим различные модели параллельного программирования и поговорим о том, как Rust поможет вам смело программировать в нескольких потоках.
Глава 17, ООП. Рассматриваются идиомы Rust в сравнении с принципами объектно-дезориентированного программирования, с которыми вы могли встречаться раньше.
Глава 18, шаблоны. Это справочник по шаблонам (patterns) и сопоставлению шаблонов (pattern matching), что является мощным способом выражения своих идей в программах Rust.
Глава 19, дополнения. Содержит сложные и интересные темы, включая опасное программирование (unsafe Rust), макросы, дополнительная информация про lifetimes, traits, types, functions и closures.
Глава 20, реализация web-сервера. В главе 20 мы создадим целостный проект: многоуровневый, многопоточный web-сервер!
И наконец, многие дополнения содержат полезную информацию по языку, в формате справочника. Appendix A содержит ключевые слова Rust, Appendix B содержит операторы и символы Rust, Appendix C охватывает производные признаки (derivable traits), предоставляемые стандартной библиотекой, Appendix D рассматривает некоторые полезные инструменты разработки, и Appendix E объясняет выпуски Rust (editions). В Appendix F вы сможете найти переводы книги, а Appendix G расскажет, как был создан Rust.
Также не может быть неправильного способа читать эту книгу: если вам интересно заглянуть вперед, то не стесняйтесь. Вы сможете впоследствии вернуться к предыдущим главам, если запутаетесь. Просто делайте то, что вам подходит.
Эта книга (английская версия) была сгенерирована из исходных файлов, опубликованных на GitHub [2].
[Глава 1. Знакомство с Rust]
В этой главе будут рассмотрены темы:
• Установка Rust на Linux, macOS и Windows. • Написание программы, которая печатает в консоли "Hello, world!". • Использование cargo, менеджера пакетов и система сборки Rust.
Установка. Первый шаг для установки Rust - это загрузка специальной программы-установщика rustup. Это утилита командной строки, специально предназначенная для управления версиями Rust и связанными с ним утилитами.
Примечание: если вы по какой-то причине предпочли не использовать установщик rustup, то см. описание альтернативных методов установки Rust [3].
Описанные далее шаги установят самую свежую и стабильную версию компилятора Rust. Это даст гарантию, что все примеры из этой книги также будут успешно компилироваться с более новыми версиями Rust. Вывод может незначительно отличаться между версиями, потому что в Rust часто улучшаются сообщения об ошибках и предупреждения. Другими словами, любая более новая установленная вами, стабильная версия Rust должна работать, как ожидалось, в соответствии с содержимой этой книги.
Нотация командной строки. В этой главе и во всей книге [1] будут показаны команды, вводимые в терминале. Все строки команд, которые вы должны ввести в терминале, начинаются с символа $. Этот символ просто обозначает приглашение терминала (обычно так выглядит командная строка терминала Linux), и его вводить не нужно. Строки, которые не начинаются с символа $, обычно показывают выводимые сообщения от предыдущей команды. Примеры, специфичные для PowerShell (платформа Windows), вместо символа $ для той же цели будут использовать символ > (типовое приглашение командной строки CMD.exe).
Установка rustup на Linux или macOS. Если вы используете Linux или macOS, то откройте терминал и выполните следующую команду:
$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
Эта команда загрузит скрипт, и запустит установку под управлением утилиты rustup, которая установит последнюю стабильную версию Rust. Возможно вы получите запрос ввода вашего пароля. Если установка прошла успешно, то появится следующая строка сообщения:
Rust is installed now. Great!
Также вам понадобится линкер, с помощью него Rust соединит друг с другом результаты компиляции отдельных модулей в один файл. Скорее всего, у вас линкер уже установлен. Если же вы увидите ошибки линкера, то следует установить компилятор C (gcc), при его установки обычно также установится и линкер. Некоторые пакеты Rust зависят от кода C, и поэтому понадобится компилятор C.
На macOS вы можете получить компилятор C, выполнив следующую команду:
$ xcode-select --install
Пользователи Linux обычно должны установить GCC или Clang, в соответствии с документацией своего дистрибутива. Например, если вы используете Ubuntu, то можете установить пакет build-essential.
Установка rustup на Windows. Перейдите по ссылке https://www.rust-lang.org/tools/install, и следуйте её инструкциям для установки Rust. На некоторой точке инсталляции вам предложат установить Visual Studio. Это нужно для того, чтобы установить компилятор C/C++, линкер и традиционные стандартные библиотеки, необходимые для компиляции программ под Windows. Если на этом шаге вам понадобится больше помощи, то см. [4].
Остальные команды, используемые в этой книге, работают одинаково и в cmd.exe, и в PowerShell. Если есть какие-либо отличия, то это будет объясняться специально.
Чтобы проверить, корректно ли установлен Rust, откройте командную строку (шелл), и введите команду:
$ rustc --version
В ответ вы должны увидеть номер версии, хэш фиксации (commit hash) и дату фиксации (commit date) для последней стабильной версии релиза, в следующем формате:
rustc x.y.z (abcabcabc yyyy-mm-dd)
Если вы увидели эту информацию, то значит Rust установлен правильно. Если вы не увидели эту информацию, то проверьте содержимое системной переменной %PATH%, в ней должен быть прописан каталог, где находятся исполняемые утилиты Rust.
В Windows CMD используйте:
> echo %PATH%
В PowerShell используйте:
> echo $env:Path
На Linux и macOS используйте:
$ echo $PATH
Если путь в переменной PATH указан правильно, но Rust все еще не работает, есть несколько мест в Интернете, где можно получить помощь. Одно из них это комьюнити Rustaceans [5] (глупое прозвище, которым называют себя разработчики Rust).
Обновление и деинсталляция. Как только Rust установлен, обновление на новую версию релиза становится простым. Из шелла запустите следующий скрипт обновления:
$ rustup update
Для деинсталляции Rust и rustup запустите следующий скрипт из вашего шелла:
$ rustup self uninstall
Локальная документация. Инсталляция Rust также включает копию документации, которую можно читать без доступа к Интернет (offline). Чтобы открыть эту документацию в браузере, запустите команду:
$ rustup doc
Каждый раз, когда тип или функция предоставляется стандартной библиотекой, и вы не уверены, что она делает или как ее использовать, используйте документацию по прикладному программному интерфейсу (API).
[Hello, World!]
Теперь, после того как вы установили Rust, настало время написать свою первую программу Rust. Стало традицией при обучении новому языку - написать простейшую программу, которая напечатает текст "Hello, world!".
Примечание: эта книга подразумевает у читателя базовые знания по использованию командной строки операционной системы. Rust не устанавливает специальных требований о том, как вы редактируете текст программы, или где вы размещаете свой код. Так что вы можете пользоваться либо любимым текстовым редактором, или использовать среду разработки (integrated development environment, IDE) вместо командной строки. Многие IDE в настоящее время декларируют некую поддержку Rust, см. документацию на соответствующую IDE. Команда разработчиков Rust сосредоточилась на реализации качественной поддержки IDE на основе rust-analyzer, см. Appendix D [1].
Создание директории проекта. Первое, что надо сделать - создать каталог, где будет находиться код вашей программы Rust. Не имеет значения, где будет размещена эта папка на диске, но для упрощения использования упражнений и проектов из этой книги, рекомендуется создать отдельную папку projects в вашей домашней директории, и уже в ней создавать папки для ваших проектов.
Откройте терминал, и введите следующие команды, чтобы создать директорию projects и директорию для проекта "Hello, world!" в этой директории.
Для Linux, macOS и PowerShell на Windows выполните команды:
$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world
Для Windows CMD введите следующее:
> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world
Написание и запуск программы Rust. На этом шаге мы создадим новый исходный файл кода и назовем его main.rs. Файлы кода на языке Rust всегда заканчиваются расширением .rs. Если вы составляете имя файла из нескольких слов, то принято их разделять символом подчеркивания. Например, используйте имя файла hello_world.rs вместо helloworld.rs.
Создайте в текстовом редакторе main.rs, чтобы он находился в директории projects/hello_world, и введите в него текст из листинга 1-1:
Имя файла: main.rs
fn main() {
println!("Hello, world!");
}
Listing 1-1: программа, которая печатает Hello, world!
Сохраните этот файл, и вернитесь обратно в окно терминала с текущей директорией ~/projects/hello_world. Для компиляции и запуска программы на Linux или macOS введите следующие команды:
$ rustc main.rs
$ ./main
Hello, world!
На Windows вместо ./main введите .\main.exe:
> rustc main.rs
> .\main.exe
Hello, world!
Независимо от вашей операционной системы, в терминале вы должны увидеть печать строки текста Hello, world!
Анатомия программы на языке Rust. Следующие строки определяют функцию с именем main:
fn main() {
}
Имя функции main особенное, оно определяет самый первый код, который запустится при выполнении программы Rust. В нашем примере у функции main нет параметров, поэтому внутри круглых скобок () ничего не указано.
Тело функции окружено фигурными скобками {}. Rust требует все тела функций определять внутри фигурных скобок. Один из стилей программирования предлагает размещать открывающую скобку { на той же строке, что и имя функции, сразу после круглых скобок, через пробел.
Примечание: если вы хотите придерживаться стандартного стиля написания кода в своих проектах Rust, то можете использовать утилиту автоматического форматирования rustfmt, чтобы привести ваш код к определенному стилю (больше информации про rustfmt см. в Appendix D [1]). Утилита rustfmt устанавливается на компьютер вместе с компилятором rustc.
Тело функции main состоит в нашем случае из следующего кода:
println!("Hello, world!");
Эта строка делает всю работу в этой маленькой программе: она печатает текст на экране. Здесь следует сделать 4 важных замечания.
Во-первых, стиль Rust подразумевает использовать для отступа кода в теле функции четыре пробела, а не символ табуляции.
Во-вторых, println! вызывает макрос Rust. Если бы мы место этого делали вызов функции, то использовали бы println (без !). Более подробно про макросы Rust можно прочитать в главе 19. Пока что вам просто нужно знать, что использование ! после имени означает вызов макроса вместо обычной функции, и этот макрос не всегда следует таким же правилам, что и функции.
В третьих, здесь вы видите строку "Hello, world!". Мы передаем эту строку как аргумент для println!, и в результате эта строка будет напечатана на экране.
И наконец, мы заканчиваем строку оператора на символ точки с запятой (;). Это показывает, что выражение закончилось, и дальше может начинаться следующее выражение. Большинство строк кода Rust заканчиваются точкой с запятой.
Компиляция и запуск. Это разные шаги, так что рассмотрим их по отдельности.
Перед запуском программы Rust нам надо её скомпилировать, используя компилятор rustc, указав ему имя модуля исходного кода, примерно так:
$ rustc main.rs
Если вы раньше уже имели дело с кодом на языке C или C++, то можете заметить, что это похоже на компиляцию с помощью gcc или clang. После успешной компиляции будет сгенерирован исполняемый бинарный код.
На Linux, macOS и PowerShell Windows вы можете увидеть полученный исполняемый код, если введете в вашем шелле команду ls:
$ ls
main main.rs
На Linux и macOS вы увидите 2 файла. При использовании PowerShell на Windows вы увидите те же самые 3 файла, которые можно увидеть, используя CMD. При использовании CMD на Windows введите следующую команду (опция /B говорит, что показывать надо только имена файлов):
> dir /B
main.exe
main.pdb
main.rs
В этом списке мы видим файл исходного кода с расширением .rs, исполняемый файл (main.exe на Windows, просто main на всех других платформах). Также при использовании Windows будет еще третий файл с расширением .pdb, содержащий отладочную информацию. Отсюда мы можем запустить полученный исполняемый код следующими командами.
На Linux или MacOS:
$ ./main
На Windows:
> .\main.exe
Если вы знакомы с динамическим языком программирования, таким как Ruby, Python или JavaScript, то заметите разницу, что там компиляция и запуск программы не выполнялась отдельными шагами. Rust относится к языкам типа "ahead-of-time compiled", т. е. для получения рабочего кода программу нужно предварительно компилировать, и после этого скомпилированную программу можно запускать отдельно, в том числе и на другой машине, даже если сам Rust на ней не установлен. Если у вас есть какой-то файл .rb, .py или .js, то для их запуска требуется, чтобы в системе были установлены Ruby, Python или JavaScript соответственно. Но для этих языков вам требуется только одна команда для запуска программы. Каждый из описанных способов имеет свои достоинства и недостатки, связанные с дизайном языка.
Простое компилирования с помощь rustc хорошо подходит для относительно простых программ, однако если ваш проект разрастается, то вероятно понадобится централизованно управлять всеми опциями и упростить совместное использование вашего кода. Все это облегчает инструмент Cargo.
[Hello, Cargo!]
Cargo это система сборки и менеджер пакетов Rust. Большинство Rustacean-цев используют этот инструмент для управления своими проектами Rust, потому что Cargo делает за вас очень многое - сборка кода, загрузка библиотек, от которых зависит ваш код, и сборка этих библиотек (эти библиотеки, которые нужны для работы программы, называются зависимостями, dependencies).
Простые программы Rust, такие как демонстрированная выше Hello World, не нуждаются ни в каких зависимостях. Если бы мы выполнили компиляцию проекта "Hello, world!" с помощью Cargo, то будет использоваться только та часть Cargo, которая занимается сборкой кода. По мере того, как вы пишете все более сложный код программы на Rust, вы будете добавлять зависимости, и если вы начнете создавать свой проект с помощью Cargo, то добавление зависимостей будет значительно упрощаться.
Поскольку подавляющее большинство проектов Rust используют Cargo, остальная часть этой книги предполагает, что вы тоже используете Cargo. Cargo поставляется установленным вместе с Rust, если вы использовали официальные инсталляторы, как это обсуждалось выше в секции "Установка". Если вы установили Rust каким-то другим способом, то проверьте, установлен ли у Вас Cargo, вводом следующей командой:
$ cargo --version
Если в ответ на эту команду вы увидели номер версии, то значит Cargo установлен. Если вы видите ошибку, такую как "command not found", просмотрите документацию по вашему методу установки для получения описания, как отдельно установить Cargo.
Создание проекта с помощью Cargo. Давайте создадим новый проект, используя Cargo, и посмотрим, чем он будет отличаться от оригинального проекта "Hello, world!". Перейдите обратно в свою директорию projects (или в папку, которую вы решили использовать для своих проектов). Затем, в любой операционной системе, запустите следующее:
$ cargo new hello_cargo
$ cd hello_cargo
Первая команда создаст новую директорию hello_cargo и в ней проект. Мы назвали наш проект hello_cargo, и Cargo создаст его файлы в директории с таким же именем.
Перейдите в директорию hello_cargo и посмотрите, какие там находятся файлы. Вы увидите, что Cargo там сгенерировал 2 файла и одну директорию: файлы Cargo.toml и .gitignore, папку src, и в папке src будет находиться файл main.rs.
Файлы Git не будут генерироваться, если вы запустите команду cargo new в существующем репозитории Git; вы можете отменить это поведение, используя команду cargo new --vcs=git.
Примечание: Git это общеизвестная система управления версиями. Вы можете изменить команду cargo new для использования другой системы управления версиями, или не использовать систему управления версиями, используя флаг --vcs. Для получения доступных опций запустите команду cargo new --help.
Откройте файл Cargo.toml в своем любимом текстовом редакторе (под Windows я обычно использую Notepad2, под Ubuntu использую gedit или nano). В этом файле вы увидите текст, подобный листингу 1-2.
Имя файла: Cargo.toml
[package]
name="hello_cargo"
version="0.1.0"
edition="2021"
[dependencies]
Listing 1-2: Содержимое файла настроек Cargo.toml, сгенерированного командой cargo new.
Это файл манифеста Cargo, котором находятся опции в формате TOML (Tom’s Obvious, Minimal Language), этот формат был выбран для хранения конфигурации Cargo (документацию по различным ключам и опциям см. на страничке [7]).
Первая строка [package] это заголовок секции, показывающий, что следующие операторы будут конфигурировать пакет программы. По мере добавления дополнительной информации в этот файл мы будем также добавлять и другие секции.
Следующие 3 строки устанавливают конфигурационную информацию Cargo, необходимую для компиляции вашей программы: имя программы (name), версию (version), а также редакцию используемой среды Rust (edition). Больше информации о ключе edition можно найти в Appendix E [1].
Последняя строка [dependencies] определяет для вас начало секции, где можно перечислить любые необходимые зависимости для вашей программы, или пакеты библиотек. В Rust пакеты кода называются "crates" (переводится как ящики). Для этого простого примера проекта нам не потребуются никакие другие crates, однако в первом проекте главы 2, мы будем использовать эту секцию зависимостей.
Теперь откройте файл src/main.rs:
Имя файла: src/main.rs
fn main() {
println!("Hello, world!");
}
Cargo сгенерировал для все программу "Hello, world!", точно такую же, как мы писали в листинге 1-1. До сих пор различия между нашим проектом и проектом, сгенерированным Cargo, заключаются в том, что Cargo поместил код в отдельный каталог src, и у нас есть конфигурационный файл Cargo.toml в верхнем каталоге (ну и конечно был автоматически сгенерирован репозиторий Git для проекта).
Cargo подразумевает, что файлы исходного кода вашего проекта находятся внутри директории src. Директория верхнего уровня проекта (в нашем примере это папка hello_cargo) предназначена только для файлов README, лицензионной информации, конфигурационных файлов, и всего остального, что не относится к вашему коду. Использование Cargo помогает вам организовать ваши проекты стандартным и удобным образом. Есть место для всего, и все на своих местах.
Если вы уже начали свой проект без Cargo, как мы это делали вначале с проектом "Hello, world!", вы можете преобразовать его в проект под управлением Cargo. Для этого переместите свой код проекта в директорию src, и создайте соответствующий файл конфигурации Cargo.toml.
Сборка и запуск проекта Cargo. Давайте теперь посмотрим, чем отличается компиляция и запуск программы "Hello, world!" под управлением Cargo. Из директории hello_cargo сборка проекта запустится вводом следующей команды:
$ cargo build
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs
Эта команда создаст исполняемый файл target/debug/hello_cargo (или target\debug\hello_cargo.exe на Windows) вместо того, чтобы создавать его в вашей текущей директории. По той причине, что по умолчанию сборка делается в состоянии для отладки (debug build), Cargo поместит двоичные файлы результатов сборки в папку с именем debug. Вы можете запустить исполняемый файл следующей командой (на Windows это должна быть команда .\target\debug\hello_cargo.exe):
$ ./target/debug/hello_cargo
Hello, world!
Если все хорошо, то вы увидите напечатанное в терминале сообщение Hello, world. Запуск cargo build для первого раза также создаст на верхнем уровне файл Cargo.lock. Этот файл отслеживает точные зависимости в вашем проекте. У этого проекта нет зависимостей, так что файл будет почти пустой. Никогда не следует редактировать этот файл вручную; содержимым этого файла управляет сам Cargo.
cargo run. Мы построили проект и запустили его программу двумя отдельными командами cargo build и ./target/debug/hello_cargo, но мы также можем все это сделать одной командой cargo run:
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/hello_cargo`
Hello, world!
Использование cargo run удобнее, чем запускать cargo build и затем вводить полный путь до исполняемого бинарника, так что большинство разработчиков используют cargo run.
Обратите внимание, что при запуске cargo run мы не увидели сообщений, что произошла компиляция проекта. Дело в том, что ранее мы уже собрали проект командой cargo build, и перед запуском cargo run не было внесено в исходный код никаких изменений. Cargo определила, что никакие файлы исходного кода не поменялись, так что не требуется пересобирать исходный код, чтобы сгенерировать и запустить бинарник. Если же мы поменяем содержимое модулей исходного кода, то Cargo пересоберет проект перед его запуском, и тогда вы увидите сообщение наподобие такого:
$ cargo run
Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
Running `target/debug/hello_cargo`
Hello, world!
cargo check. Cargo также предоставляет команду cargo check. Эта команда быстро проверит ваш код на предмет его возможной компиляции (проверит синтаксис на ошибки), но не будет при этом генерировать исполняемый файл:
$ cargo check
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Для чего может понадобиться такая команда? Иногда, что особенно верно для больших проектов, команда cargo check может отработать намного быстрее, потому что пропускается шаг генерации исполняемого кода. Если вы постоянно проверяете свою работу командой cargo check, то можете значительно ускорить процесс разработки. В конце работы вы можете все также запустить cargo build или cargo run, что сгенерирует бинарный исполняемый код.
Дополнительное достоинство Cargo в том, что её команды всегда одни и те же, независимо от используемой операционной системы. Так что с этого момента мы больше не будем давать отдельные инструкции по запуску команд для Linux, macOS, отличающихся от команд Windows.
Сборка для релиза. Когда ваш проект полностью готов к релизу, вы можете запустить команду cargo build --release, чтобы скомпилировать программу проекта с разрешенными оптимизациями. Эта команда создаст исполняемый код в каталоге target/release вместо каталога target/debug. Оптимизации позволят вашему коду Rust работать быстрее, однако несколько увеличит время компиляции. Это одна из причин, почему существует 2 различных профиля компиляции: одна для разработки, и другая для построения конечной версии программы, которая должна работать на стороне пользователя максимально эффективно (т. е. занимать как можно меньше места и работать как можно быстрее).
Для чего нужен Cargo. С простыми проектами Cargo не дает значительных преимуществ по сравнению с простым использованием rustc, однако это может сильно измениться по мере того, как ваши программы станут все более замысловатыми. Как только программа разрастется до нескольких файлов, или когда для неё понадобятся зависимости, то намного проще будет использовать Cargo для координации сборки.
Несмотря на то, что проект hello_cargo прост, в нем все равно используется большая часть реальной оснастки, которую вы будете применять для повседневной работы в Rust. Фактически для работы над любыми существующими проектами вы можете использовать следующие команды, чтобы извлечь код с помощью Git, перейти в каталог проекта и выполнить сборку:
$ git clone example.org/someproject
$ cd someproject
$ cargo build
Для дополнительной информации про Cargo см. документацию [6].
[Как итог]
Вы получили хорошую стартовую точку для начала работы с Rust. В этой главе мы познакомились со следующим:
• Как установить последнюю стабильную версию Rust с помощью инсталлятора rustup. • Как обновиться на более новую версию Rust. • Как пользоваться локальной документацией. • Написали и запустили программу "Hello, world!", используя компилятор rustc. • Создали и запустили новый проект под управлением Cargo.
В главе 2 мы рассмотрим создание программы игры. Если вы хотите начать с изучения того, как общие концепции программирования работают в Rust, см. главу 3, а затем можете вернуться к главе 2.
[Ссылки]
1. The Rust Programming Language book site:rust-lang.org. 2. rust-lang / book site:github.com. 3. Other Rust Installation Methods site:rust-lang.org. 4. MSVC prerequisites site:rust-lang.github.io. 5. Rust Community site:rust-lang.org. 6. The Cargo Book site:rust-lang.org. 7. Cargo Manifest Format site:rust-lang.org.