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

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

Первыми из частей системы модулей мы разберём пакеты и крейты.

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

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

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

Корень крейта (crate root) — это исходный файл, с которого компилятор Rust начинает работу и который образует корневой модуль крейта (подробно модули разберём в разделе «Модули: область видимости и приватность»).

Пакет (package) — это набор из одного или нескольких крейтов, реализующий некоторую функциональность. В пакете есть файл 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: каждый файл станет отдельным бинарным крейтом.