ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 11.01.2024
Просмотров: 1123
Скачиваний: 5
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Вам также понадобится компоновщик - программа, которую Rust использует для объединения своих скомпилированных выходных данных в один файл. Скорее всего, он у вас уже есть. При возникновении ошибок компоновки, вам следует установить компилятор C, который обычно будет включать в себя и компоновщик. Компилятор C
также полезен, потому что некоторые распространённые пакеты Rust зависят от кода C и нуждаются в компиляторе C.
На macOS вы можете получить компилятор C, выполнив команду:
Пользователи Linux, как правило, должны устанавливать GCC или Clang в соответствии с документацией их дистрибутива. Например, при использовании Ubuntu можно установить пакет build-essential
Установка rustup на Windows
В Windows перейдите на https://www.rust-lang.org/tools/install и следуйте инструкциям по установке Rust. В какой-то момент установки вы получите сообщение о том, что вам также потребуются инструменты сборки MSVC для Visual Studio 2013 или более поздней версии. Чтобы получить инструменты сборки, вам необходимо установить
Visual Studio
2022
. Когда вас спросят, что именно установить, укажите:
“Desktop Development with C++”
The Windows 10 or 11 SDK
Английский языковой пакет вместе с любым другим языковым пакетом по вашему выбору.
В остальной части этой книги используются команды, которые работают как в cmd.exe,
так и в PowerShell. При наличии специфических различий мы объясним, что необходимо сделать в таких случаях.
Устранение возможных ошибок
Чтобы проверить, правильно ли у вас установлен Rust, откройте оболочку и введите эту строку:
Вы должны увидеть номер версии, хэш коммита и дату выпуска последней стабильной версии в следующем формате:
$
xcode-select --install
$
rustc --version rustc x.y.z (abcabcabc yyyy-mm-dd)
Если вы видите эту информацию, вы успешно установили Rust! Если вы не видите эту информацию, убедитесь, что Rust находится в вашей системной переменной
%PATH%
следующим образом:
В Windows CMD:
В PowerShell:
В Linux и macOS:
Если все правильно, а Rust по-прежнему не работает, есть несколько мест, где вы можете получить помощь. Самый простой — это канал #beginners на официальном канале Rust в
Discord
. Там вы можете пообщаться с другими rustaceans (глупое прозвище, которым мы называем себя), которые могут вам помочь. Другие замечательные ресурсы включают форум пользователей и
Stack Overflow
Обновление и удаление
После установки Rust через rustup при выходе новой версии Rust обновление до последней версии не составит труда. В вашем терминале запустите следующий скрипт обновления:
Чтобы удалить Rust и rustup
, выполните следующую команду:
Локальная документация
Установка Rust также включает в себя локальную копию документации, поэтому вы можете читать её в оффлайн режиме. Запустите rustup doc
, чтобы открыть локальную документацию в браузере.
Каждый раз, когда есть какой-либо тип или какая-либо функция, предоставляемые стандартной библиотекой, а вы не знаете, что они делают и как их использовать,
>
echo
%PATH%
>
echo
$env
:Path echo $PATH
$
rustup update
$
rustup self uninstall
воспользуйтесь документацией по интерфейсу прикладного программирования (API) для поиска!
Привет, мир!
Итак, когда Rust уже установлен, можно приступать к написанию вашей первой программы. Общая традиция при изучении нового языка программирования - писать маленькую программу, которая печатает в строке вывода "Hello, world!"
. Давайте сделаем то же самое.
Примечание: Эта книга предполагает наличие базового навыка работы с командной строкой. Rust не предъявляет особых требований к тому, каким инструментарием вы пользуетесь для редактирования или хранения вашего кода, поэтому если вы предпочитаете использовать интегрированную среду разработки (IDE) вместо командной строки, смело используйте вашу любимую IDE. Многие IDE сейчас в той или иной степени поддерживают Rust; подробности можно узнать из документации к IDE. Команда Rust сосредоточилась на обеспечении отличной поддержки IDE с помощью rust-analyzer
. Более подробную информацию смотрите в
Приложении
D
!
Создание папки проекта
Прежде всего начнём с создания директории, в которой будем сохранять наш код на языке Rust. На самом деле не важно, где сохранять наш код. Однако, для упражнений и проектов, обсуждаемых в данной книге, мы советуем создать директорию projects в вашем домашнем каталоге, там же и хранить в будущем код программ из книги.
Откройте терминал и введите следующие команды для того, чтобы создать директорию
projects для хранения кода разных проектов, и, внутри неё, директорию hello_world для проекта “Hello, world!”.
Для Linux, macOS и PowerShell на Windows, введите:
Для Windows в CMD, введите:
Написание и запуск первой Rust программы
$
mkdir /projects
$
cd
/projects
$
mkdir hello_world
$
cd hello_world
> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world
Затем создайте новый исходный файл и назовите его main.rs. Файлы Rust всегда заканчиваются расширением .rs. Если вы используете более одного слова в имени файла,
принято разделять их символом подчёркивания. Например, используйте hello_world.rs
вместо helloworld.rs.
Теперь откроем файл main.rs для редактирования и введём следующие строки кода:
Название файла: main.rs
Листинг 1-1: Программа которая печатает
Hello, world!
Сохраните файл и вернитесь в окно терминала в каталог /projects/hello_world. В Linux или macOS введите следующие команды для компиляции и запуска файла:
В Windows, введите команду
.\main.exe вместо
./main
:
Независимо от операционной системы, строка
Hello, world!
должна напечататься в окне вашего терминала. Если вы не увидели вывода, вернитесь в часть "Решение проблем"
"Troubleshooting"
раздела "Установка" для получения помощи.
Если напечаталось
Hello, world!
, то примите наши поздравления! Вы написали программу на Rust, что делает вас Rust программистом — добро пожаловать!
Анатомия программы на Rust
Давайте рассмотрим «Hello, world!» программу в деталях. Вот первая часть головоломки:
Эти строки определяют функцию с именем main
. Функция main особенная: это всегда первый код, который запускается в каждой исполняемой программе Rust. Первая строка объявляет функцию с именем main
, которая не имеет параметров и ничего не возвращает. Если бы были параметры, они бы заключались в круглые скобки
()
fn main
() { println!
(
"Hello, world!"
);
}
$
rustc main.rs
$
./main
Hello, world!
> rustc main.rs
> .\main.exe
Hello, world! fn main
() {
}
Тело функции заключено в
{}
. Rust требует фигурных скобок вокруг всех тел функций.
Хороший стиль — поместить открывающую фигурную скобку на ту же строку, что и объявление функции, добавив между ними один пробел.
Примечание. Если вы хотите придерживаться стандартного стиля в проектах на
Rust, вы можете использовать инструмент автоматического форматирования под названием rustfmt для форматирования кода в определённом стиле (подробнее о rustfmt в
Приложении D
). ). Команда Rust включила этот инструмент в стандартный дистрибутив Rust, например, rustc
, поэтому он уже должен быть установлен на вашем компьютере!
Тело функции main содержит следующий код:
Эта строка делает всю работу в этой маленькой программе: печатает текст на экран.
Можно заметить четыре важных детали.
Первая, не столь заметная, - в стиле Rust для отступа используются четыре пробела, а не знак табуляции.
Во-вторых, println!
вызывает макрос Rust. Если бы вместо этого была вызвана функция,
она была бы введена как println
(без
!
). Мы обсудим макросы Rust более подробно в
Главе 19. Сейчас вам просто нужно знать, что использование
!
означает, что вы вызываете макрос вместо обычной функции, и что макросы не всегда следуют тем же правилам, что и функции.
В-третьих, вы видите строку "Hello, world!"
. Мы передаём её в качестве аргумента макросу println!
, и она выводится на экран.
В-четвёртых, мы заканчиваем строку точкой с запятой (
;
), которая указывает на то, что это выражение закончилось и готово начаться следующее. Большинство строк кода на
Rust заканчиваются точкой с запятой.
Компиляция и выполнение кода являются отдельными шагами
Вы только что запустили только что созданную программу, так что давайте рассмотрим каждый шаг в этом процессе.
Перед запуском программы на Rust вы должны скомпилировать её с помощью компилятора Rust, введя команду rustc и передав ей имя вашего исходного файла,
например:
println!
(
"Hello, world!"
);
Если у вас есть опыт работы с C или C++, вы заметите, что это похоже на gcc или clang
После успешной компиляции Rust выводит двоичный исполняемый файл.
На Linux, macOS и с PowerShell на Windows вы можете увидеть исполняемый файл, введя команду ls в своём терминале. В Linux и macOS вы увидите два файла. С PowerShell в
Windows вы увидите те же три файла, что и при использовании CMD.
В CMD на Windows следует ввести следующие команды:
Это показывает исходный код файла с расширением .rs, исполняемый файл (main.exe на
Windows, но main на всех других платформах) и, при использовании Windows, файл,
содержащий отладочную информацию с расширением .pdb. Отсюда вы запускаете файлы
main или main.exe, например:
Если ваш main.rs — это ваша программа «Hello, world!», эта строка выведет в терминал
Hello, world!
Если вы лучше знакомы с динамическими языками, такими как Ruby, Python или
JavaScript, возможно, вы не привыкли компилировать и запускать программу как отдельные шаги. Rust — это предварительно скомпилированный язык, то есть вы можете скомпилировать программу и передать исполняемый файл кому-то другому, и он сможет запустить его даже без установленного Rust. Если вы даёте кому-то файл .rb , .py или .js, у него должна быть установлена реализация Ruby, Python или JavaScript (соответственно).
Но в этих языках вам нужна только одна команда для компиляции и запуска вашей программы. В дизайне языков программирования всё — компромисс.
Компиляция с помощью rustc подходит для простых программ, но по мере роста вашего проекта вы захотите управлять всеми параметрами и упростить передачу кода.
Далее мы познакомим вас с инструментом Cargo, который поможет вам писать программы из реального мира на Rust.
$
rustc main.rs
$
ls main main.rs
> dir /B %= the /B option says to only show the file names =% main.exe main.pdb main.rs
$
./main
# для Linux
>
.\main.exe
# для Windows
Привет, Cargo!
Cargo - это система сборки и менеджер пакетов Rust. Большая часть разработчиков используют данный инструмент для управления проектами, потому что Cargo выполняет за вас множество задач, таких как сборка кода, загрузка библиотек, от которых зависит ваш код, и создание этих библиотек. (Мы называем библиотеки, которые нужны вашему коду, зависимостями.)
Самые простые программы на Rust, подобные той, которую мы написали, не имеют никаких зависимостей. Если бы мы сделали проект «Hello, world!» с Cargo, он бы использовал только ту часть Cargo, которая отвечает за компиляцию вашего кода. По мере написания более сложных программ на Rust вы будете добавлять зависимости, а если вы начнёте проект с использованием Cargo, добавлять зависимости станет намного проще.
Так как большая часть проектов использует Cargo, то остальная часть книги подразумевает, что вы также используете Cargo. Cargo устанавливается вместе с Rust при использовании официальных установщиков обсуждаемых в разделе "Установка Rust"
Если вы установили Rust другим способом, то проверьте, работает ли он, введя команду проверки версии Cargo в терминале:
Если команда выдала номер версии, то значит Cargo установлен. Если вы видите ошибку,
вроде command not found
("команда не найдена"), загляните в документацию для использованного вами способа установки, чтобы выполнить установку Cargo отдельно.
Создание проекта с помощью Cargo
Давайте создадим новый проект с помощью Cargo и посмотрим, как он отличается от нашего начального проекта "Hello, world!". Перейдите обратно в папку projects (или любую другую, где вы решили сохранять код). Затем, в любой операционный системе,
запустите команду:
Первая команда создаёт новый каталог и проект с именем hello_cargo. Мы назвали наш проект hello_cargo, и Cargo создаёт свои файлы в каталоге с тем же именем.
Перейдём в каталог hello_cargo и посмотрим файлы. Увидим, что Cargo сгенерировал два файла и одну директорию: файл Cargo.toml и каталог src с файлом main.rs внутри.
Кроме того, cargo инициализировал новый репозиторий Git вместе с файлом .gitignore.
Файлы Git не будут сгенерированы, если вы запустите cargo new в существующем
$
cargo --version
$
cargo new hello_cargo
$
cd hello_cargo
репозитории Git; вы можете изменить это поведение, используя cargo new --vcs=git
Примечание: Git - это распространённая система контроля версий. Вы можете изменить cargo new на использование другой системы контроля версий или не использовать никакой системы контроля версий с помощью флага
--vcs
Выполните команду cargo new --help
, чтобы увидеть доступные опции.
Откройте файл Cargo.toml в любом текстовом редакторе. Он должен выглядеть как код в листинге 1-2.
Файл: Cargo.toml
Листинг 1-2: Содержимое файла Cargo.toml, сгенерированного командой
cargo new
Это файл в формате
TOML
(Tom’s Obvious, Minimal Language), который является форматом конфигураций Cargo.
Первая строка,
[package]
, является заголовочной секцией, которая указывает что следующие инструкции настраивают пакет. По мере добавления больше информации в данный файл, будет добавляться больше секций и инструкций (строк).
Следующие три строки задают информацию о конфигурации, необходимую Cargo для компиляции вашей программы: имя, версию и редакцию Rust, который будет использоваться. Мы поговорим о ключе edition в
Приложении E
Последняя строка,
[dependencies]
является началом секции для списка любых зависимостей вашего проекта. В Rust, это внешние пакеты кода, на которые ссылаются ключевым словом crate. Нам не нужны никакие зависимости в данном проекте, но мы будем использовать их в первом проекте главы 2, так что нам пригодится данная секция зависимостей потом.
Откройте файл src/main.rs и загляните в него:
Файл : src/main.rs
[package]
name =
"hello_cargo"
version =
"0.1.0"
edition =
"2021"
[dependencies]
fn main
() { println!
(
"Hello, world!"
);
}
Cargo сгенерировал для вас программу «Hello, world!», точно такую же, как та, которую мы написали в Листинге 1-1! На данный момент различия между нашим проектом и проектом, сгенерированным Cargo, заключаются в том, что Cargo поместил код в каталог
src, и у нас есть файл конфигурации Cargo.toml в каталоге верхнего уровня.
Cargo ожидает, что ваши исходные файлы находятся внутри каталога src. Каталог верхнего уровня проекта предназначен только для файлов README, информации о лицензии, файлы конфигурации и чего то ещё не относящего к вашему коду.
Использование Cargo помогает организовывать проект. Есть место для всего и все находится на своём месте.
Если вы начали проект без использования Cargo, как мы делали для "Hello, world!"
проекта, то можно конвертировать его в проект с использованием Cargo. Переместите код в подкаталог src и создайте соответствующий файл Cargo.toml в папке.
Сборка и запуск Cargo проекта
Посмотрим, в чем разница при сборке и запуске программы "Hello, world!" с помощью
Cargo. В каталоге hello_cargo соберите проекта следующей командой:
Эта команда создаёт исполняемый файл в target/debug/hello_cargo (или
target\debug\hello_cargo.exe в Windows), а не в вашем текущем каталоге. Поскольку стандартная сборка является отладочной, Cargo помещает двоичный файл в каталог с именем debug. Вы можете запустить исполняемый файл с помощью этой команды:
Если все хорошо, то
Hello, world!
печатается в терминале. Запуск команды cargo build в первый раз также приводит к созданию нового файла Cargo.lock в папке верхнего уровня. Данный файл хранит точные версии зависимостей вашего проекта. Так как у нас нет зависимостей, то файл пустой. Вы никогда не должны менять этот файл вручную:
Cargo сам управляет его содержимым для вас.
Мы только что собрали проект командой cargo build и запустили его из
./target/debug/hello_cargo
. Но мы также можем использовать команду cargo run для компиляции кода и затем его запуска одной командой:
$
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
# or .\target\debug\hello_cargo.exe on Windows
Hello, world!
$
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 компилирует hello_cargo
. Cargo выяснил, что файлы не изменились, поэтому не стал пересобирать, а просто запустил бинарный файл. Если бы вы изменили свой исходный код, Cargo пересобрал бы проект перед его запуском, и вы бы увидели этот вывод:
Cargo также предоставляет команду, называемую cargo check
. Эта команда быстро проверяет ваш код, чтобы убедиться, что он компилируется, но не создаёт исполняемый файл:
Почему вам не нужен исполняемый файл? Часто cargo check выполняется намного быстрее, чем cargo build
, поскольку пропускает этап создания исполняемого файла.
Если вы постоянно проверяете свою работу во время написания кода, использование cargo check ускорит процесс информирования вас о том, что ваш проект всё ещё
компилируется! Таким образом, многие Rustacean периодически запускают cargo check
,
когда пишут свои программы, чтобы убедиться, что она компилируется. Затем они запускают cargo build
, когда готовы использовать исполняемый файл.
Давайте подытожим, что мы уже узнали о Cargo:
Мы можем создать проект с помощью cargo new можно собирать проект, используя команду cargo build
,
можно одновременно собирать и запускать проект одной командой cargo run
,
можно собрать проект для проверки ошибок с помощью cargo check
, не тратя время на кодогенерацию исполняемого файла,
cargo сохраняет результаты сборки не в директорию с исходным кодом, а в отдельный каталог target/debug.
Дополнительным преимуществом использования Cargo является то, что его команды одинаковы для разных операционных систем. С этой точки зрения, мы больше не будем предоставлять отдельные инструкции для Linux, macOS или Windows.
$
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
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Сборка финальной версии (Release)
Когда проект, наконец, готов к релизу, можно использовать команду cargo build -- release для его компиляции с оптимизацией. Данная команда создаёт исполняемый файл в папке target/release в отличии от папки target/debug. Оптимизации делают так, что
Rust код работает быстрее, но их включение увеличивает время компиляции. По этой причине есть два отдельных профиля: один для разработки, когда нужно осуществлять сборку быстро и часто, и другой, для сборки финальной программы, которую будете отдавать пользователям, которая готова к работе и будет выполняться максимально быстро. Если вы замеряете время выполнения вашего кода, убедитесь, что собрали проект с оптимизацией cargo build --release и тестируете исполняемый файл из папки
target/release.
1 2 3 4 5 6 7 8 9 ... 62
Обновление и удаление
После установки Rust через rustup при выходе новой версии Rust обновление до последней версии не составит труда. В вашем терминале запустите следующий скрипт обновления:
Чтобы удалить Rust и rustup
, выполните следующую команду:
Локальная документация
Установка Rust также включает в себя локальную копию документации, поэтому вы можете читать её в оффлайн режиме. Запустите rustup doc
, чтобы открыть локальную документацию в браузере.
Каждый раз, когда есть какой-либо тип или какая-либо функция, предоставляемые стандартной библиотекой, а вы не знаете, что они делают и как их использовать,
>
echo
%PATH%
>
echo
$env
:Path echo $PATH
$
rustup update
$
rustup self uninstall
воспользуйтесь документацией по интерфейсу прикладного программирования (API) для поиска!
Привет, мир!
Итак, когда Rust уже установлен, можно приступать к написанию вашей первой программы. Общая традиция при изучении нового языка программирования - писать маленькую программу, которая печатает в строке вывода "Hello, world!"
. Давайте сделаем то же самое.
Примечание: Эта книга предполагает наличие базового навыка работы с командной строкой. Rust не предъявляет особых требований к тому, каким инструментарием вы пользуетесь для редактирования или хранения вашего кода, поэтому если вы предпочитаете использовать интегрированную среду разработки (IDE) вместо командной строки, смело используйте вашу любимую IDE. Многие IDE сейчас в той или иной степени поддерживают Rust; подробности можно узнать из документации к IDE. Команда Rust сосредоточилась на обеспечении отличной поддержки IDE с помощью rust-analyzer
. Более подробную информацию смотрите в
Приложении
D
!
Создание папки проекта
Прежде всего начнём с создания директории, в которой будем сохранять наш код на языке Rust. На самом деле не важно, где сохранять наш код. Однако, для упражнений и проектов, обсуждаемых в данной книге, мы советуем создать директорию projects в вашем домашнем каталоге, там же и хранить в будущем код программ из книги.
Откройте терминал и введите следующие команды для того, чтобы создать директорию
projects для хранения кода разных проектов, и, внутри неё, директорию hello_world для проекта “Hello, world!”.
Для Linux, macOS и PowerShell на Windows, введите:
Для Windows в CMD, введите:
Написание и запуск первой Rust программы
$
mkdir /projects
$
cd
/projects
$
mkdir hello_world
$
cd hello_world
> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world
Затем создайте новый исходный файл и назовите его main.rs. Файлы Rust всегда заканчиваются расширением .rs. Если вы используете более одного слова в имени файла,
принято разделять их символом подчёркивания. Например, используйте hello_world.rs
вместо helloworld.rs.
Теперь откроем файл main.rs для редактирования и введём следующие строки кода:
Название файла: main.rs
Листинг 1-1: Программа которая печатает
Hello, world!
Сохраните файл и вернитесь в окно терминала в каталог /projects/hello_world. В Linux или macOS введите следующие команды для компиляции и запуска файла:
В Windows, введите команду
.\main.exe вместо
./main
:
Независимо от операционной системы, строка
Hello, world!
должна напечататься в окне вашего терминала. Если вы не увидели вывода, вернитесь в часть "Решение проблем"
"Troubleshooting"
раздела "Установка" для получения помощи.
Если напечаталось
Hello, world!
, то примите наши поздравления! Вы написали программу на Rust, что делает вас Rust программистом — добро пожаловать!
Анатомия программы на Rust
Давайте рассмотрим «Hello, world!» программу в деталях. Вот первая часть головоломки:
Эти строки определяют функцию с именем main
. Функция main особенная: это всегда первый код, который запускается в каждой исполняемой программе Rust. Первая строка объявляет функцию с именем main
, которая не имеет параметров и ничего не возвращает. Если бы были параметры, они бы заключались в круглые скобки
()
fn main
() { println!
(
"Hello, world!"
);
}
$
rustc main.rs
$
./main
Hello, world!
> rustc main.rs
> .\main.exe
Hello, world! fn main
() {
}
Тело функции заключено в
{}
. Rust требует фигурных скобок вокруг всех тел функций.
Хороший стиль — поместить открывающую фигурную скобку на ту же строку, что и объявление функции, добавив между ними один пробел.
Примечание. Если вы хотите придерживаться стандартного стиля в проектах на
Rust, вы можете использовать инструмент автоматического форматирования под названием rustfmt для форматирования кода в определённом стиле (подробнее о rustfmt в
Приложении D
). ). Команда Rust включила этот инструмент в стандартный дистрибутив Rust, например, rustc
, поэтому он уже должен быть установлен на вашем компьютере!
Тело функции main содержит следующий код:
Эта строка делает всю работу в этой маленькой программе: печатает текст на экран.
Можно заметить четыре важных детали.
Первая, не столь заметная, - в стиле Rust для отступа используются четыре пробела, а не знак табуляции.
Во-вторых, println!
вызывает макрос Rust. Если бы вместо этого была вызвана функция,
она была бы введена как println
(без
!
). Мы обсудим макросы Rust более подробно в
Главе 19. Сейчас вам просто нужно знать, что использование
!
означает, что вы вызываете макрос вместо обычной функции, и что макросы не всегда следуют тем же правилам, что и функции.
В-третьих, вы видите строку "Hello, world!"
. Мы передаём её в качестве аргумента макросу println!
, и она выводится на экран.
В-четвёртых, мы заканчиваем строку точкой с запятой (
;
), которая указывает на то, что это выражение закончилось и готово начаться следующее. Большинство строк кода на
Rust заканчиваются точкой с запятой.
Компиляция и выполнение кода являются отдельными шагами
Вы только что запустили только что созданную программу, так что давайте рассмотрим каждый шаг в этом процессе.
Перед запуском программы на Rust вы должны скомпилировать её с помощью компилятора Rust, введя команду rustc и передав ей имя вашего исходного файла,
например:
println!
(
"Hello, world!"
);
Если у вас есть опыт работы с C или C++, вы заметите, что это похоже на gcc или clang
После успешной компиляции Rust выводит двоичный исполняемый файл.
На Linux, macOS и с PowerShell на Windows вы можете увидеть исполняемый файл, введя команду ls в своём терминале. В Linux и macOS вы увидите два файла. С PowerShell в
Windows вы увидите те же три файла, что и при использовании CMD.
В CMD на Windows следует ввести следующие команды:
Это показывает исходный код файла с расширением .rs, исполняемый файл (main.exe на
Windows, но main на всех других платформах) и, при использовании Windows, файл,
содержащий отладочную информацию с расширением .pdb. Отсюда вы запускаете файлы
main или main.exe, например:
Если ваш main.rs — это ваша программа «Hello, world!», эта строка выведет в терминал
Hello, world!
Если вы лучше знакомы с динамическими языками, такими как Ruby, Python или
JavaScript, возможно, вы не привыкли компилировать и запускать программу как отдельные шаги. Rust — это предварительно скомпилированный язык, то есть вы можете скомпилировать программу и передать исполняемый файл кому-то другому, и он сможет запустить его даже без установленного Rust. Если вы даёте кому-то файл .rb , .py или .js, у него должна быть установлена реализация Ruby, Python или JavaScript (соответственно).
Но в этих языках вам нужна только одна команда для компиляции и запуска вашей программы. В дизайне языков программирования всё — компромисс.
Компиляция с помощью rustc подходит для простых программ, но по мере роста вашего проекта вы захотите управлять всеми параметрами и упростить передачу кода.
Далее мы познакомим вас с инструментом Cargo, который поможет вам писать программы из реального мира на Rust.
$
rustc main.rs
$
ls main main.rs
> dir /B %= the /B option says to only show the file names =% main.exe main.pdb main.rs
$
./main
# для Linux
>
.\main.exe
# для Windows
Привет, Cargo!
Cargo - это система сборки и менеджер пакетов Rust. Большая часть разработчиков используют данный инструмент для управления проектами, потому что Cargo выполняет за вас множество задач, таких как сборка кода, загрузка библиотек, от которых зависит ваш код, и создание этих библиотек. (Мы называем библиотеки, которые нужны вашему коду, зависимостями.)
Самые простые программы на Rust, подобные той, которую мы написали, не имеют никаких зависимостей. Если бы мы сделали проект «Hello, world!» с Cargo, он бы использовал только ту часть Cargo, которая отвечает за компиляцию вашего кода. По мере написания более сложных программ на Rust вы будете добавлять зависимости, а если вы начнёте проект с использованием Cargo, добавлять зависимости станет намного проще.
Так как большая часть проектов использует Cargo, то остальная часть книги подразумевает, что вы также используете Cargo. Cargo устанавливается вместе с Rust при использовании официальных установщиков обсуждаемых в разделе "Установка Rust"
Если вы установили Rust другим способом, то проверьте, работает ли он, введя команду проверки версии Cargo в терминале:
Если команда выдала номер версии, то значит Cargo установлен. Если вы видите ошибку,
вроде command not found
("команда не найдена"), загляните в документацию для использованного вами способа установки, чтобы выполнить установку Cargo отдельно.
Создание проекта с помощью Cargo
Давайте создадим новый проект с помощью Cargo и посмотрим, как он отличается от нашего начального проекта "Hello, world!". Перейдите обратно в папку projects (или любую другую, где вы решили сохранять код). Затем, в любой операционный системе,
запустите команду:
Первая команда создаёт новый каталог и проект с именем hello_cargo. Мы назвали наш проект hello_cargo, и Cargo создаёт свои файлы в каталоге с тем же именем.
Перейдём в каталог hello_cargo и посмотрим файлы. Увидим, что Cargo сгенерировал два файла и одну директорию: файл Cargo.toml и каталог src с файлом main.rs внутри.
Кроме того, cargo инициализировал новый репозиторий Git вместе с файлом .gitignore.
Файлы Git не будут сгенерированы, если вы запустите cargo new в существующем
$
cargo --version
$
cargo new hello_cargo
$
cd hello_cargo
репозитории Git; вы можете изменить это поведение, используя cargo new --vcs=git
Примечание: Git - это распространённая система контроля версий. Вы можете изменить cargo new на использование другой системы контроля версий или не использовать никакой системы контроля версий с помощью флага
--vcs
Выполните команду cargo new --help
, чтобы увидеть доступные опции.
Откройте файл Cargo.toml в любом текстовом редакторе. Он должен выглядеть как код в листинге 1-2.
Файл: Cargo.toml
Листинг 1-2: Содержимое файла Cargo.toml, сгенерированного командой
cargo new
Это файл в формате
TOML
(Tom’s Obvious, Minimal Language), который является форматом конфигураций Cargo.
Первая строка,
[package]
, является заголовочной секцией, которая указывает что следующие инструкции настраивают пакет. По мере добавления больше информации в данный файл, будет добавляться больше секций и инструкций (строк).
Следующие три строки задают информацию о конфигурации, необходимую Cargo для компиляции вашей программы: имя, версию и редакцию Rust, который будет использоваться. Мы поговорим о ключе edition в
Приложении E
Последняя строка,
[dependencies]
является началом секции для списка любых зависимостей вашего проекта. В Rust, это внешние пакеты кода, на которые ссылаются ключевым словом crate. Нам не нужны никакие зависимости в данном проекте, но мы будем использовать их в первом проекте главы 2, так что нам пригодится данная секция зависимостей потом.
Откройте файл src/main.rs и загляните в него:
Файл : src/main.rs
[package]
name =
"hello_cargo"
version =
"0.1.0"
edition =
"2021"
[dependencies]
fn main
() { println!
(
"Hello, world!"
);
}
Cargo сгенерировал для вас программу «Hello, world!», точно такую же, как та, которую мы написали в Листинге 1-1! На данный момент различия между нашим проектом и проектом, сгенерированным Cargo, заключаются в том, что Cargo поместил код в каталог
src, и у нас есть файл конфигурации Cargo.toml в каталоге верхнего уровня.
Cargo ожидает, что ваши исходные файлы находятся внутри каталога src. Каталог верхнего уровня проекта предназначен только для файлов README, информации о лицензии, файлы конфигурации и чего то ещё не относящего к вашему коду.
Использование Cargo помогает организовывать проект. Есть место для всего и все находится на своём месте.
Если вы начали проект без использования Cargo, как мы делали для "Hello, world!"
проекта, то можно конвертировать его в проект с использованием Cargo. Переместите код в подкаталог src и создайте соответствующий файл Cargo.toml в папке.
Сборка и запуск Cargo проекта
Посмотрим, в чем разница при сборке и запуске программы "Hello, world!" с помощью
Cargo. В каталоге hello_cargo соберите проекта следующей командой:
Эта команда создаёт исполняемый файл в target/debug/hello_cargo (или
target\debug\hello_cargo.exe в Windows), а не в вашем текущем каталоге. Поскольку стандартная сборка является отладочной, Cargo помещает двоичный файл в каталог с именем debug. Вы можете запустить исполняемый файл с помощью этой команды:
Если все хорошо, то
Hello, world!
печатается в терминале. Запуск команды cargo build в первый раз также приводит к созданию нового файла Cargo.lock в папке верхнего уровня. Данный файл хранит точные версии зависимостей вашего проекта. Так как у нас нет зависимостей, то файл пустой. Вы никогда не должны менять этот файл вручную:
Cargo сам управляет его содержимым для вас.
Мы только что собрали проект командой cargo build и запустили его из
./target/debug/hello_cargo
. Но мы также можем использовать команду cargo run для компиляции кода и затем его запуска одной командой:
$
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
# or .\target\debug\hello_cargo.exe on Windows
Hello, world!
$
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 компилирует hello_cargo
. Cargo выяснил, что файлы не изменились, поэтому не стал пересобирать, а просто запустил бинарный файл. Если бы вы изменили свой исходный код, Cargo пересобрал бы проект перед его запуском, и вы бы увидели этот вывод:
Cargo также предоставляет команду, называемую cargo check
. Эта команда быстро проверяет ваш код, чтобы убедиться, что он компилируется, но не создаёт исполняемый файл:
Почему вам не нужен исполняемый файл? Часто cargo check выполняется намного быстрее, чем cargo build
, поскольку пропускает этап создания исполняемого файла.
Если вы постоянно проверяете свою работу во время написания кода, использование cargo check ускорит процесс информирования вас о том, что ваш проект всё ещё
компилируется! Таким образом, многие Rustacean периодически запускают cargo check
,
когда пишут свои программы, чтобы убедиться, что она компилируется. Затем они запускают cargo build
, когда готовы использовать исполняемый файл.
Давайте подытожим, что мы уже узнали о Cargo:
Мы можем создать проект с помощью cargo new можно собирать проект, используя команду cargo build
,
можно одновременно собирать и запускать проект одной командой cargo run
,
можно собрать проект для проверки ошибок с помощью cargo check
, не тратя время на кодогенерацию исполняемого файла,
cargo сохраняет результаты сборки не в директорию с исходным кодом, а в отдельный каталог target/debug.
Дополнительным преимуществом использования Cargo является то, что его команды одинаковы для разных операционных систем. С этой точки зрения, мы больше не будем предоставлять отдельные инструкции для Linux, macOS или Windows.
$
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
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Сборка финальной версии (Release)
Когда проект, наконец, готов к релизу, можно использовать команду cargo build -- release для его компиляции с оптимизацией. Данная команда создаёт исполняемый файл в папке target/release в отличии от папки target/debug. Оптимизации делают так, что
Rust код работает быстрее, но их включение увеличивает время компиляции. По этой причине есть два отдельных профиля: один для разработки, когда нужно осуществлять сборку быстро и часто, и другой, для сборки финальной программы, которую будете отдавать пользователям, которая готова к работе и будет выполняться максимально быстро. Если вы замеряете время выполнения вашего кода, убедитесь, что собрали проект с оптимизацией cargo build --release и тестируете исполняемый файл из папки
target/release.
1 2 3 4 5 6 7 8 9 ... 62
Привет, мир!
Итак, когда Rust уже установлен, можно приступать к написанию вашей первой программы. Общая традиция при изучении нового языка программирования - писать маленькую программу, которая печатает в строке вывода "Hello, world!"
. Давайте сделаем то же самое.
Примечание: Эта книга предполагает наличие базового навыка работы с командной строкой. Rust не предъявляет особых требований к тому, каким инструментарием вы пользуетесь для редактирования или хранения вашего кода, поэтому если вы предпочитаете использовать интегрированную среду разработки (IDE) вместо командной строки, смело используйте вашу любимую IDE. Многие IDE сейчас в той или иной степени поддерживают Rust; подробности можно узнать из документации к IDE. Команда Rust сосредоточилась на обеспечении отличной поддержки IDE с помощью rust-analyzer
. Более подробную информацию смотрите в
Приложении
D
!
Создание папки проекта
Прежде всего начнём с создания директории, в которой будем сохранять наш код на языке Rust. На самом деле не важно, где сохранять наш код. Однако, для упражнений и проектов, обсуждаемых в данной книге, мы советуем создать директорию projects в вашем домашнем каталоге, там же и хранить в будущем код программ из книги.
Откройте терминал и введите следующие команды для того, чтобы создать директорию
projects для хранения кода разных проектов, и, внутри неё, директорию hello_world для проекта “Hello, world!”.
Для Linux, macOS и PowerShell на Windows, введите:
Для Windows в CMD, введите:
Написание и запуск первой Rust программы
$
mkdir /projects
$
cd
/projects
$
mkdir hello_world
$
cd hello_world
> mkdir "%USERPROFILE%\projects"
> cd /d "%USERPROFILE%\projects"
> mkdir hello_world
> cd hello_world
Затем создайте новый исходный файл и назовите его main.rs. Файлы Rust всегда заканчиваются расширением .rs. Если вы используете более одного слова в имени файла,
принято разделять их символом подчёркивания. Например, используйте hello_world.rs
вместо helloworld.rs.
Теперь откроем файл main.rs для редактирования и введём следующие строки кода:
Название файла: main.rs
Листинг 1-1: Программа которая печатает
Hello, world!
Сохраните файл и вернитесь в окно терминала в каталог /projects/hello_world. В Linux или macOS введите следующие команды для компиляции и запуска файла:
В Windows, введите команду
.\main.exe вместо
./main
:
Независимо от операционной системы, строка
Hello, world!
должна напечататься в окне вашего терминала. Если вы не увидели вывода, вернитесь в часть "Решение проблем"
"Troubleshooting"
раздела "Установка" для получения помощи.
Если напечаталось
Hello, world!
, то примите наши поздравления! Вы написали программу на Rust, что делает вас Rust программистом — добро пожаловать!
Анатомия программы на Rust
Давайте рассмотрим «Hello, world!» программу в деталях. Вот первая часть головоломки:
Эти строки определяют функцию с именем main
. Функция main особенная: это всегда первый код, который запускается в каждой исполняемой программе Rust. Первая строка объявляет функцию с именем main
, которая не имеет параметров и ничего не возвращает. Если бы были параметры, они бы заключались в круглые скобки
()
fn main
() { println!
(
"Hello, world!"
);
}
$
rustc main.rs
$
./main
Hello, world!
> rustc main.rs
> .\main.exe
Hello, world! fn main
() {
}
Тело функции заключено в
{}
. Rust требует фигурных скобок вокруг всех тел функций.
Хороший стиль — поместить открывающую фигурную скобку на ту же строку, что и объявление функции, добавив между ними один пробел.
Примечание. Если вы хотите придерживаться стандартного стиля в проектах на
Rust, вы можете использовать инструмент автоматического форматирования под названием rustfmt для форматирования кода в определённом стиле (подробнее о rustfmt в
Приложении D
). ). Команда Rust включила этот инструмент в стандартный дистрибутив Rust, например, rustc
, поэтому он уже должен быть установлен на вашем компьютере!
Тело функции main содержит следующий код:
Эта строка делает всю работу в этой маленькой программе: печатает текст на экран.
Можно заметить четыре важных детали.
Первая, не столь заметная, - в стиле Rust для отступа используются четыре пробела, а не знак табуляции.
Во-вторых, println!
вызывает макрос Rust. Если бы вместо этого была вызвана функция,
она была бы введена как println
(без
!
). Мы обсудим макросы Rust более подробно в
Главе 19. Сейчас вам просто нужно знать, что использование
!
означает, что вы вызываете макрос вместо обычной функции, и что макросы не всегда следуют тем же правилам, что и функции.
В-третьих, вы видите строку "Hello, world!"
. Мы передаём её в качестве аргумента макросу println!
, и она выводится на экран.
В-четвёртых, мы заканчиваем строку точкой с запятой (
;
), которая указывает на то, что это выражение закончилось и готово начаться следующее. Большинство строк кода на
Rust заканчиваются точкой с запятой.
Компиляция и выполнение кода являются отдельными шагами
Вы только что запустили только что созданную программу, так что давайте рассмотрим каждый шаг в этом процессе.
Перед запуском программы на Rust вы должны скомпилировать её с помощью компилятора Rust, введя команду rustc и передав ей имя вашего исходного файла,
например:
println!
(
"Hello, world!"
);
Если у вас есть опыт работы с C или C++, вы заметите, что это похоже на gcc или clang
После успешной компиляции Rust выводит двоичный исполняемый файл.
На Linux, macOS и с PowerShell на Windows вы можете увидеть исполняемый файл, введя команду ls в своём терминале. В Linux и macOS вы увидите два файла. С PowerShell в
Windows вы увидите те же три файла, что и при использовании CMD.
В CMD на Windows следует ввести следующие команды:
Это показывает исходный код файла с расширением .rs, исполняемый файл (main.exe на
Windows, но main на всех других платформах) и, при использовании Windows, файл,
содержащий отладочную информацию с расширением .pdb. Отсюда вы запускаете файлы
main или main.exe, например:
Если ваш main.rs — это ваша программа «Hello, world!», эта строка выведет в терминал
Hello, world!
Если вы лучше знакомы с динамическими языками, такими как Ruby, Python или
JavaScript, возможно, вы не привыкли компилировать и запускать программу как отдельные шаги. Rust — это предварительно скомпилированный язык, то есть вы можете скомпилировать программу и передать исполняемый файл кому-то другому, и он сможет запустить его даже без установленного Rust. Если вы даёте кому-то файл .rb , .py или .js, у него должна быть установлена реализация Ruby, Python или JavaScript (соответственно).
Но в этих языках вам нужна только одна команда для компиляции и запуска вашей программы. В дизайне языков программирования всё — компромисс.
Компиляция с помощью rustc подходит для простых программ, но по мере роста вашего проекта вы захотите управлять всеми параметрами и упростить передачу кода.
Далее мы познакомим вас с инструментом Cargo, который поможет вам писать программы из реального мира на Rust.
$
rustc main.rs
$
ls main main.rs
> dir /B %= the /B option says to only show the file names =% main.exe main.pdb main.rs
$
./main
# для Linux
>
.\main.exe
# для Windows
Привет, Cargo!
Cargo - это система сборки и менеджер пакетов Rust. Большая часть разработчиков используют данный инструмент для управления проектами, потому что Cargo выполняет за вас множество задач, таких как сборка кода, загрузка библиотек, от которых зависит ваш код, и создание этих библиотек. (Мы называем библиотеки, которые нужны вашему коду, зависимостями.)
Самые простые программы на Rust, подобные той, которую мы написали, не имеют никаких зависимостей. Если бы мы сделали проект «Hello, world!» с Cargo, он бы использовал только ту часть Cargo, которая отвечает за компиляцию вашего кода. По мере написания более сложных программ на Rust вы будете добавлять зависимости, а если вы начнёте проект с использованием Cargo, добавлять зависимости станет намного проще.
Так как большая часть проектов использует Cargo, то остальная часть книги подразумевает, что вы также используете Cargo. Cargo устанавливается вместе с Rust при использовании официальных установщиков обсуждаемых в разделе "Установка Rust"
Если вы установили Rust другим способом, то проверьте, работает ли он, введя команду проверки версии Cargo в терминале:
Если команда выдала номер версии, то значит Cargo установлен. Если вы видите ошибку,
вроде command not found
("команда не найдена"), загляните в документацию для использованного вами способа установки, чтобы выполнить установку Cargo отдельно.
Создание проекта с помощью Cargo
Давайте создадим новый проект с помощью Cargo и посмотрим, как он отличается от нашего начального проекта "Hello, world!". Перейдите обратно в папку projects (или любую другую, где вы решили сохранять код). Затем, в любой операционный системе,
запустите команду:
Первая команда создаёт новый каталог и проект с именем hello_cargo. Мы назвали наш проект hello_cargo, и Cargo создаёт свои файлы в каталоге с тем же именем.
Перейдём в каталог hello_cargo и посмотрим файлы. Увидим, что Cargo сгенерировал два файла и одну директорию: файл Cargo.toml и каталог src с файлом main.rs внутри.
Кроме того, cargo инициализировал новый репозиторий Git вместе с файлом .gitignore.
Файлы Git не будут сгенерированы, если вы запустите cargo new в существующем
$
cargo --version
$
cargo new hello_cargo
$
cd hello_cargo
Примечание: Git - это распространённая система контроля версий. Вы можете изменить cargo new на использование другой системы контроля версий или не использовать никакой системы контроля версий с помощью флага
--vcs
Выполните команду cargo new --help
, чтобы увидеть доступные опции.
Откройте файл Cargo.toml в любом текстовом редакторе. Он должен выглядеть как код в листинге 1-2.
Файл: Cargo.toml
Листинг 1-2: Содержимое файла Cargo.toml, сгенерированного командой
cargo new
Это файл в формате
TOML
(Tom’s Obvious, Minimal Language), который является форматом конфигураций Cargo.
Первая строка,
[package]
, является заголовочной секцией, которая указывает что следующие инструкции настраивают пакет. По мере добавления больше информации в данный файл, будет добавляться больше секций и инструкций (строк).
Следующие три строки задают информацию о конфигурации, необходимую Cargo для компиляции вашей программы: имя, версию и редакцию Rust, который будет использоваться. Мы поговорим о ключе edition в
Приложении E
Последняя строка,
[dependencies]
является началом секции для списка любых зависимостей вашего проекта. В Rust, это внешние пакеты кода, на которые ссылаются ключевым словом crate. Нам не нужны никакие зависимости в данном проекте, но мы будем использовать их в первом проекте главы 2, так что нам пригодится данная секция зависимостей потом.
Откройте файл src/main.rs и загляните в него:
Файл : src/main.rs
[package]
name =
"hello_cargo"
version =
"0.1.0"
edition =
"2021"
[dependencies]
fn main
() { println!
(
"Hello, world!"
);
}
Cargo сгенерировал для вас программу «Hello, world!», точно такую же, как та, которую мы написали в Листинге 1-1! На данный момент различия между нашим проектом и проектом, сгенерированным Cargo, заключаются в том, что Cargo поместил код в каталог
src, и у нас есть файл конфигурации Cargo.toml в каталоге верхнего уровня.
Cargo ожидает, что ваши исходные файлы находятся внутри каталога src. Каталог верхнего уровня проекта предназначен только для файлов README, информации о лицензии, файлы конфигурации и чего то ещё не относящего к вашему коду.
Использование Cargo помогает организовывать проект. Есть место для всего и все находится на своём месте.
Если вы начали проект без использования Cargo, как мы делали для "Hello, world!"
проекта, то можно конвертировать его в проект с использованием Cargo. Переместите код в подкаталог src и создайте соответствующий файл Cargo.toml в папке.
Сборка и запуск Cargo проекта
Посмотрим, в чем разница при сборке и запуске программы "Hello, world!" с помощью
Cargo. В каталоге hello_cargo соберите проекта следующей командой:
Эта команда создаёт исполняемый файл в target/debug/hello_cargo (или
target\debug\hello_cargo.exe в Windows), а не в вашем текущем каталоге. Поскольку стандартная сборка является отладочной, Cargo помещает двоичный файл в каталог с именем debug. Вы можете запустить исполняемый файл с помощью этой команды:
Если все хорошо, то
Hello, world!
печатается в терминале. Запуск команды cargo build в первый раз также приводит к созданию нового файла Cargo.lock в папке верхнего уровня. Данный файл хранит точные версии зависимостей вашего проекта. Так как у нас нет зависимостей, то файл пустой. Вы никогда не должны менять этот файл вручную:
Cargo сам управляет его содержимым для вас.
Мы только что собрали проект командой cargo build и запустили его из
./target/debug/hello_cargo
. Но мы также можем использовать команду cargo run для компиляции кода и затем его запуска одной командой:
$
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
# or .\target\debug\hello_cargo.exe on Windows
Hello, world!
$
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 компилирует hello_cargo
. Cargo выяснил, что файлы не изменились, поэтому не стал пересобирать, а просто запустил бинарный файл. Если бы вы изменили свой исходный код, Cargo пересобрал бы проект перед его запуском, и вы бы увидели этот вывод:
Cargo также предоставляет команду, называемую cargo check
. Эта команда быстро проверяет ваш код, чтобы убедиться, что он компилируется, но не создаёт исполняемый файл:
Почему вам не нужен исполняемый файл? Часто cargo check выполняется намного быстрее, чем cargo build
, поскольку пропускает этап создания исполняемого файла.
Если вы постоянно проверяете свою работу во время написания кода, использование cargo check ускорит процесс информирования вас о том, что ваш проект всё ещё
компилируется! Таким образом, многие Rustacean периодически запускают cargo check
,
когда пишут свои программы, чтобы убедиться, что она компилируется. Затем они запускают cargo build
, когда готовы использовать исполняемый файл.
Давайте подытожим, что мы уже узнали о Cargo:
Мы можем создать проект с помощью cargo new можно собирать проект, используя команду cargo build
,
можно одновременно собирать и запускать проект одной командой cargo run
,
можно собрать проект для проверки ошибок с помощью cargo check
, не тратя время на кодогенерацию исполняемого файла,
cargo сохраняет результаты сборки не в директорию с исходным кодом, а в отдельный каталог target/debug.
Дополнительным преимуществом использования Cargo является то, что его команды одинаковы для разных операционных систем. С этой точки зрения, мы больше не будем предоставлять отдельные инструкции для Linux, macOS или Windows.
$
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
Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs
Сборка финальной версии (Release)
Когда проект, наконец, готов к релизу, можно использовать команду cargo build -- release для его компиляции с оптимизацией. Данная команда создаёт исполняемый файл в папке target/release в отличии от папки target/debug. Оптимизации делают так, что
Rust код работает быстрее, но их включение увеличивает время компиляции. По этой причине есть два отдельных профиля: один для разработки, когда нужно осуществлять сборку быстро и часто, и другой, для сборки финальной программы, которую будете отдавать пользователям, которая готова к работе и будет выполняться максимально быстро. Если вы замеряете время выполнения вашего кода, убедитесь, что собрали проект с оптимизацией cargo build --release и тестируете исполняемый файл из папки
target/release.
1 2 3 4 5 6 7 8 9 ... 62
Cargo как Конвенция
В простых проектах Cargo не даёт больших преимуществ по сравнению с использованием rustc
, но он проявит себя, когда ваши программы станут более сложными. Когда программы вырастают до нескольких файлов или нуждаются в зависимостях, гораздо проще позволить Cargo координировать сборку.
Не смотря на то, что проект hello_cargo простой, теперь он использует большую часть реального инструментария, который вы будете повседневно использовать в вашей карьере, связанной с Rust. Когда потребуется работать над проектами размещёнными в сети, вы сможете просто использовать следующую последовательность команд для получения кода с помощью Git, перехода в каталог проекта, сборку проекта:
Для получения дополнительной информации о Cargo ознакомьтесь с его документацией
Итоги
Теперь вы готовы начать своё Rust путешествие! В данной главе вы изучили как:
установить последнюю стабильную версию Rust, используя rustup
,
обновить Rust до последней версии,
открыть локально установленную документацию,
написать и запустить программу типа "Hello, world!", используя напрямую компилятор rustc
,
создать и запустить новый проект, используя соглашения и команды Cargo.
$
git clone example.org/someproject
$
cd someproject
$
cargo build
Это отличное время для создания более существенной программы, чтобы привыкнуть читать и писать код на языке Rust. Итак, в главе 2 мы построим программу для игры в угадай число. Если вы предпочитаете начать с изучения того, как работают общие концепции программирования в Rust, обратитесь к главе 3, а затем вернитесь к главе 2.
Программируем игру Угадайка
Давайте погрузимся в Rust, вместе выполнив практический проект! Эта глава познакомит с несколькими распространёнными концепциями Rust, показав, как использовать их в реальной программе. Вы узнаете о let
, match
, методах, ассоциированных функциях,
использовании внешних пакетов и многом другом! В следующих главах рассмотрим эти идеи более подробно. В этой главе вы на практике познакомитесь с основами.
Мы реализуем классическую для начинающих программистов задачу: игру в угадывание.
Вот как это работает: программа генерирует случайное целое число в диапазоне от 1 до
100. Затем она предлагает игроку ввести отгадку. После ввода отгадки программа укажет,
является ли отгадка слишком заниженной или слишком завышенной. Если отгадка верна,
игра напечатает поздравительное сообщение и завершится.
Настройка нового проекта
Для настройки нового проекта перейдите в каталог projects, который вы создали в главе
1, и создайте новый проект с использованием Cargo, как показано ниже:
Первая команда, cargo new
, принимает в качестве первого аргумента имя проекта
(
guessing_game
). Вторая команда изменяет каталог на новый каталог проекта.
Загляните в созданный файл Cargo.toml:
Файл: Cargo.toml
Как вы уже видели в Главе 1, cargo new создаёт программу "Hello, world!". Посмотрите файл src/main.rs:
Файл: src/main.rs
$
cargo new guessing_game
$
cd guessing_game
[package]
name =
"guessing_game"
version =
"0.1.0"
edition =
"2021"
# See more keys and their definitions at https://doc.rust- lang.org/cargo/reference/manifest.html
[dependencies]
Теперь давайте скомпилируем программу "Hello, world!" и сразу на этом же этапе запустим её с помощью команды cargo run
:
Команда run пригодится, когда необходимо ускоренно выполнить итерацию проекта,
мы так собираемся сделать в этом проекте, быстро тестируя каждую итерацию, прежде чем перейти к следующей.
Снова откройте файл src/main.rs. Весь код вы будете писать в этом файле.
Обработка отгадки
Первая часть программы игры угадывания запрашивает ввод данных пользователем,
обрабатывает их и проверяет, что вводимые данные имеют ожидаемую форму. Для начала мы позволим игроку ввести отгадку. Введите код из Листинга 2-1 в src/main.rs.
Файл: src/main.rs
Листинг 2-1: Код, который получает отгадку от пользователя и печатает её
Этот код содержит много информации, поэтому давайте рассмотрим его построчно.
Чтобы получить пользовательский ввод и затем вывести результат в качестве вывода,
fn main
() { println!
(
"Hello, world!"
);
}
$
cargo run
Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
Finished dev [unoptimized + debuginfo] target(s) in 1.50s
Running `target/debug/guessing_game`
Hello, world! use std::io; fn main
() { println!
(
"Guess the number!"
); println!
(
"Please input your guess."
); let mut guess =
String
::new(); io::stdin()
.read_line(&
mut guess)
.expect(
"Failed to read line"
); println!
(
"You guessed: {guess}"
);
}
нам нужно включить в область видимости библиотеку ввода/вывода io
. Библиотека io является частью стандартной библиотеки, известной как std
:
По умолчанию в Rust есть набор элементов, определённых в стандартной библиотеке,
которые он добавляет в область видимости каждой программы. Этот набор называется
прелюдией, и вы можете изучить его содержание в документации стандартной библиотеки
Если тип, который требуется использовать, отсутствует в прелюдии, его нужно явно ввести в область видимости с помощью оператора use
. Использование библиотеки std::io предоставляет ряд полезных функциональных возможностей, включая способность принимать пользовательский ввод.
Как уже отмечалось в главе 1, функция main является точкой входа в программу:
Синтаксис fn объявляет новую функцию, круглые скобки
()
указывают на отсутствие параметров, а фигурная скобка
{
обозначает начало тела функции.
Также в главе 1 упоминалось, что println!
- это макрос, который печатает строку на экран:
Этот код печатает подсказку об игре и запрашивает пользовательский ввод.
Хранение значений с помощью переменных
Далее мы создаём переменную для хранения пользовательского ввода, как показано ниже:
Вот теперь программа становится интересней! Очень многое происходит в этой маленькой строке. Для создания переменной мы используем оператор let
. Вот ещё
один пример:
Эта строка создаёт новую переменную с именем apples и привязывает её к значению 5.
В Rust переменные неизменяемы по умолчанию, то есть, как только мы присвоим use std::io; fn main
() { println!
(
"Guess the number!"
); println!
(
"Please input your guess."
); let mut guess =
String
::new(); let apples =
5
;
. Библиотека io является частью стандартной библиотеки, известной как std
:
По умолчанию в Rust есть набор элементов, определённых в стандартной библиотеке,
которые он добавляет в область видимости каждой программы. Этот набор называется
прелюдией, и вы можете изучить его содержание в документации стандартной библиотеки
Если тип, который требуется использовать, отсутствует в прелюдии, его нужно явно ввести в область видимости с помощью оператора use
. Использование библиотеки std::io предоставляет ряд полезных функциональных возможностей, включая способность принимать пользовательский ввод.
Как уже отмечалось в главе 1, функция main является точкой входа в программу:
Синтаксис fn объявляет новую функцию, круглые скобки
()
указывают на отсутствие параметров, а фигурная скобка
{
обозначает начало тела функции.
Также в главе 1 упоминалось, что println!
- это макрос, который печатает строку на экран:
Этот код печатает подсказку об игре и запрашивает пользовательский ввод.
Хранение значений с помощью переменных
Далее мы создаём переменную для хранения пользовательского ввода, как показано ниже:
Вот теперь программа становится интересней! Очень многое происходит в этой маленькой строке. Для создания переменной мы используем оператор let
. Вот ещё
один пример:
Эта строка создаёт новую переменную с именем apples и привязывает её к значению 5.
В Rust переменные неизменяемы по умолчанию, то есть, как только мы присвоим use std::io; fn main
() { println!
(
"Guess the number!"
); println!
(
"Please input your guess."
); let mut guess =
String
::new(); let apples =
5
;
переменной значение, значение не изменится. Мы подробно обсудим эту концепцию в разделе
«Переменные и изменчивость».
в Главе 3. Чтобы сделать переменную изменяемой, мы добавляем mut перед её именем:
Примечание: Синтаксис
//
означает начало комментария, который продолжается до конца строки. Rust игнорирует все содержимое комментариев. Подробнее о комментариях мы поговорим в главе 3
Возвращаясь к программе игры Угадайка, теперь вы знаете, что let mut guess предоставит изменяемую переменную с именем guess
. Знак равенства (
=
) сообщает
Rust, что сейчас нужно связать что-то с этой переменной. Справа от знака равенства находится значение, связанное с guess
, которое является результатом вызова функции
String::new
, возвращающей новый экземпляр
String
String
- это тип строки,
предоставляемый стандартной библиотекой, который является расширяемым фрагментом текста в кодировке UTF-8.
Синтаксис
::
в строке
::new указывает, что new является ассоциированной функцией
String типа. Ассоциированная функция - это функция, реализованная для типа, в данном случае
String
. Функция new создаёт новую, пустую строку. Функцию new можно встретить во многих типах, это типичное название для функции, которая создаёт новое значение какого-либо типа.
В целом, строка let mut guess = String::new();
создала изменяемую переменную,
которая связывается с новым, пустым экземпляром
String
. Фух!
Получение пользовательского ввода
Напомним, мы подключили функциональность ввода/вывода из стандартной библиотеки с помощью use std::io;
в первой строке программы. Теперь мы вызовем функцию stdin из модуля io
, которая позволит нам обрабатывать пользовательский ввод:
Если бы мы не импортировали библиотеку io с помощью use std::io в начале программы, мы все равно могли бы использовать эту функцию, записав вызов этой функции как std::io::stdin
. Функция stdin возвращает экземпляр std::io::Stdin
,
который является типом, представляющим дескриптор стандартного ввода для вашего терминала.
let apples =
5
;
// неизменяемая let mut bananas =
5
;
// изменяемая io::stdin()
.read_line(&
mut guess)
«Переменные и изменчивость».
в Главе 3. Чтобы сделать переменную изменяемой, мы добавляем mut перед её именем:
Примечание: Синтаксис
//
означает начало комментария, который продолжается до конца строки. Rust игнорирует все содержимое комментариев. Подробнее о комментариях мы поговорим в главе 3
Возвращаясь к программе игры Угадайка, теперь вы знаете, что let mut guess предоставит изменяемую переменную с именем guess
. Знак равенства (
=
) сообщает
Rust, что сейчас нужно связать что-то с этой переменной. Справа от знака равенства находится значение, связанное с guess
, которое является результатом вызова функции
String::new
, возвращающей новый экземпляр
String
String
- это тип строки,
предоставляемый стандартной библиотекой, который является расширяемым фрагментом текста в кодировке UTF-8.
Синтаксис
::
в строке
::new указывает, что new является ассоциированной функцией
String типа. Ассоциированная функция - это функция, реализованная для типа, в данном случае
String
. Функция new создаёт новую, пустую строку. Функцию new можно встретить во многих типах, это типичное название для функции, которая создаёт новое значение какого-либо типа.
В целом, строка let mut guess = String::new();
создала изменяемую переменную,
которая связывается с новым, пустым экземпляром
String
. Фух!
Получение пользовательского ввода
Напомним, мы подключили функциональность ввода/вывода из стандартной библиотеки с помощью use std::io;
в первой строке программы. Теперь мы вызовем функцию stdin из модуля io
, которая позволит нам обрабатывать пользовательский ввод:
Если бы мы не импортировали библиотеку io с помощью use std::io в начале программы, мы все равно могли бы использовать эту функцию, записав вызов этой функции как std::io::stdin
. Функция stdin возвращает экземпляр std::io::Stdin
,
который является типом, представляющим дескриптор стандартного ввода для вашего терминала.
let apples =
5
;
// неизменяемая let mut bananas =
5
;
// изменяемая io::stdin()
.read_line(&
mut guess)
Далее строка
.read_line(&mut guess)
вызывает метод read_line на дескрипторе стандартного ввода для получения ввода от пользователя. Мы также передаём
&mut guess в качестве аргумента read_line
, сообщая ему, в какой строке хранить пользовательский ввод. Главная задача read_line
- принять все, что пользователь вводит в стандартный ввод, и сложить это в строку (не переписывая её содержимое),
поэтому мы передаём эту строку в качестве аргумента. Строковый аргумент должен быть изменяемым, чтобы метод мог изменить содержимое строки.
Символ
&
указывает, что этот аргумент является ссылкой, который предоставляет возможность нескольким частям вашего кода получить доступ к одному фрагменту данных без необходимости копировать эти данные в память несколько раз. Ссылки - это сложная функциональная возможность, а одним из главных преимуществ Rust является безопасность и простота использования ссылок. Чтобы дописать эту программу, вам не понадобится знать много таких подробностей. Пока вам достаточно знать, что ссылки,
как и переменные, по умолчанию неизменяемы. Соответственно, чтобы сделать её
изменяемой, нужно написать
&mut guess
, а не
&guess
. (В главе 4 ссылки будут описаны более подробно).
Обработка потенциального сбоя с помощью типа Result
Мы все ещё работаем над этой строкой кода. Сейчас мы обсуждаем третью строку, но обратите внимание, что она по-прежнему является частью одной логической строки кода. Следующая часть - метод:
Мы могли бы написать этот код так:
Однако одну длинную строку трудно читать, поэтому лучше разделить её. При вызове метода с помощью синтаксиса
.method_name()
часто целесообразно вводить новую строку и другие пробельные символы, чтобы разбить длинные строки. Теперь давайте обсудим, что делает эта строка.
Как упоминалось ранее, read_line помещает всё, что вводит пользователь, в строку,
которую мы ему передаём, но также возвращает значение
Result
Result это
перечисление
, часто называемый enum, тип, который может находиться в одном из нескольких возможных состояний. Мы называем каждое такое состояние вариантом.
В главе 6 перечисления будут рассмотрены более подробно. Назначение всех типов
Result заключается в передаче информации для обработки ошибок.
Варианты
Result
:
Ok и
Err
. Вариант
Ok указывает на то, что операция прошла успешно, а внутри
Ok находится успешно сгенерированное значение. Вариант
Err
.expect(
"Failed to read line"
); io::stdin().read_line(&
mut guess).expect(
"Failed to read line"
);