Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Пакеты и крейты

Первые части системы модулей, которые мы рассмотрим, – это пакеты и крейты.

Крейт – это наименьший объем кода, который компилятор Rust рассматривает за один раз. Даже если вы запускаете rustc, а не cargo, и передаете один файл исходного кода (как мы делали еще в разделе «Основы программы на Rust» главы 1), компилятор считает этот файл крейтом. Крейты могут содержать модули, а модули могут быть определены в других файлах, которые компилируются вместе с крейтом, как мы увидим в следующих разделах.

Крейт может быть одной из двух форм: бинарным крейтом или библиотечным крейтом. Бинарные крейты – это программы, которые можно скомпилировать в исполняемый файл, который затем можно запустить, например программу командной строки или сервер. Каждый из них должен иметь функцию с именем main, которая определяет, что происходит при запуске исполняемого файла. Все крейты, которые мы создавали до сих пор, были бинарными крейтами.

Библиотечные крейты не имеют функции main и не компилируются в исполняемый файл. Вместо этого они определяют функциональность, предназначенную для совместного использования несколькими проектами. Например, крейт rand, который мы использовали в главе 2, предоставляет функциональность для генерации случайных чисел. В большинстве случаев, когда разработчики Rust говорят «крейт», они имеют в виду библиотечный крейт и используют слово «крейт» взаимозаменяемо с общим программистским термином «библиотека».

Корень крейта – это исходный файл, с которого компилятор Rust начинает работу и который образует корневой модуль вашего крейта (мы подробно объясним модули в разделе «Управление областью видимости и приватностью с помощью модулей»).

Пакет – это набор одного или нескольких крейтов, который предоставляет некоторую функциональность. Пакет содержит файл Cargo.toml, описывающий, как собирать эти крейты. Сам Cargo фактически является пакетом, который содержит бинарный крейт для инструмента командной строки, которым вы пользовались для сборки кода. Пакет Cargo также содержит библиотечный крейт, от которого зависит бинарный крейт. Другие проекты могут зависеть от библиотечного крейта Cargo, чтобы использовать ту же логику, которую использует инструмент командной строки Cargo.

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

Давайте пройдемся по тому, что происходит, когда мы создаем пакет. Сначала мы вводим команду cargo new my-project:

$ cargo new my-project
     Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs

После запуска cargo new my-project мы используем ls, чтобы увидеть, что создал Cargo. В каталоге my-project находится файл Cargo.toml, так что у нас есть пакет. Также есть каталог src, который содержит main.rs. Откройте Cargo.toml в текстовом редакторе и обратите внимание, что там нет упоминания src/main.rs. Cargo следует соглашению, по которому src/main.rs является корнем бинарного крейта с тем же именем, что и пакет. Аналогично Cargo знает: если каталог пакета содержит src/lib.rs, пакет содержит библиотечный крейт с тем же именем, что и пакет, а src/lib.rs является его корнем крейта. Cargo передает файлы корней крейтов в rustc, чтобы собрать библиотеку или бинарный файл.

Здесь у нас есть пакет, который содержит только src/main.rs, то есть он содержит только бинарный крейт с именем my-project. Если пакет содержит src/main.rs и src/lib.rs, в нем два крейта: бинарный и библиотечный, оба с тем же именем, что и пакет. Пакет может иметь несколько бинарных крейтов, если поместить файлы в каталог src/bin: каждый файл будет отдельным бинарным крейтом.