Пакети та крейти
Першими частинами модульної системи, які ми охопимо, будуть пакети та крейти.
Крейт - це найменша кількість коду, яку компілятор Rust розглядає за один раз. Навіть, якщо ви запускаєте rustc
, а не cargo
і передаєте єдиний файл з вихідним кодом (як ми це робили у секції "Написання і запуск програми на Rust" Розділу 1), компілятор розглядає цей файл як крейт. Крейти можуть містити модулі, і модулі можуть бути визначені в інших файлах, які компілюються з крейтом, як ми побачимо у наступних підрозділах.
Крейт може бути представленим у двох формах: двійковий крейт або бібліотечний крейт. Двійкові крейти - це програми, які ви можете скомпілювати у виконувані файли, що можна запустити, такі як, наприклад, програму командного рядка чи сервер. Кожен з них має містити функцію із назвою main
, яка визначає, що відбувається, коли виконуваний файл запускається. Усі крейти, що ми поки що створили, є двійковими.
Бібліотечні крейти не мають функції main
і вони не компілюються у виконуваний файл. Замість цього вони визначають функціонал, призначений для спільного використання у кількох проєктах. Наприклад, крейт rand
, який ми використовували у Розділі 2, забезпечує функціонал, що генерує рандомні числа. У більшості випадків, коли Растаціанці говорять "крейт", вони мають на увазі саме бібліотечний крейт, і вони використовують "крейт" взаємозамінно із загальною концепцією програмування "бібліотека".
Корінь крейта - це вихідний файл, з якого компілятор Rust розпочинає роботу і створює кореневий модуль вашого крейта (про модулі ми розкажемо детальніше у підрозділі “Визначення модулів для контролю області видимості та приватності” ).
Пакети - це набір одного або більше крейтів, які забезпечують набір функціоналів. Пакет містить файл Cargo.toml, який описує, як зібрати ці крейти. Cargo - це, по суті, пакет, який містить двійковий крейт для інструменту командного рядка, який ви вже використовували для збірки вашого коду. Пакет Cargo також містить бібліотечний крейт, від якого залежить двійковий крейт. Інші проєкти також можуть залежати від бібліотечного крейта Cargo, щоб використовувати таку ж саму логіку, яку використовують інструмент командного рядка Cargo.
Пакет може містити стільки двійкових крейтів, скільки ви захочете, проте не більше одного бібліотечного. Пакет повинен містити принаймні один крейт, бібліотечний чи двійковий.
Розгляньмо, що відбувається, коли ми створюємо пакет. Спочатку ми вводимо команду cargo new
:
$ cargo new my-project
Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs
Після того, як ми запустили cargo new
, ми використовуємо ls
для того, щоб побачити, що Cargo створює. У каталозі проєкту знаходиться файл 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: кожен файл буде окремим двійковим крейтом.