Разделение модулей на разные файлы

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

Например, давайте начнём с кода листинга 7-17 и первым шагом переместим модуль front_of_house в свой собственный файл src/front_of_house.rs, изменив корневой файл крейта так, чтобы он содержал код показанный в листинге 7-21. В этом случае, корневым файлом крейта является src/lib.rs, но эта процедура также работает с исполняемыми крейтами у которых корневой файл крейта src/main.rs.

Файл: src/lib.rs

mod front_of_house;

pub use crate::front_of_house::hosting;

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
    hosting::add_to_waitlist();
    hosting::add_to_waitlist();
}

Листинг 7-21. Добавление в корневой файл крейта тела модуля front_of_house (которое далее будет вынесено в src/front_of_house.rs)

И на втором шаге в содержимом src/front_of_house.rs определим тело модуля front_of_house (которое мы изъяли из src/lib.rs), как показано в листинге 7-22.

Файл: src/front_of_house.rs

pub mod hosting {
    pub fn add_to_waitlist() {}
}

Листинг 7-22. Определения тела модуля front_of_house в файле src/front_of_house.rs

Использование точки с запятой после mod front_of_house, вместо объявления начала блока, говорит Rust загрузить содержимое модуля из другого файла имеющего такое же название как и имя модуля. Продолжим наш пример и выделим модуль hosting в отдельный файл, а затем поменяем содержимое файла src/front_of_house.rs так, чтобы он содержал только объявление модуля hosting:

Файл: src/front_of_house.rs

pub mod hosting;

Затем мы создаём каталог src/front_of_house и файл src/front_of_house/hosting.rs в данной директории. Чтобы вынести модуль мы, так же как и ранее, должны выделить содержимое модуля hosting из прежнего места и перенести его в свой файл модуля hosting.rs:

Файл: src/front_of_house/hosting.rs


#![allow(unused)]
fn main() {
pub fn add_to_waitlist() {}
}

Дерево модулей остаётся прежним, а вызовы функций в eat_at_restaurant будут работать без каких-либо изменений, даже если определения будут в разных файлах. Этот метод позволяет перемещать модули в новые файлы по мере их разрастания.

Обратите внимание на то, что выражение pub use crate::front_of_house::hosting в файле src/lib.rs не претерпело каких-либо изменений после переноса модулей в отдельные файлы. В то же время благодаря этому use не добавило какого-либо влияния на то какие файлы будут скомпилированы как часть крейта. Ключевое слово mod объявляет модули, а Rust просматривает файл с тем же именем, что и модуль: так он определяет код, который входит в этот модуль.

Итог

Rust позволяет разбить пакет на несколько крейтов и крейт на модули, так что вы можете ссылаться на элементы определённые в одном модуле из другого модуля. Это можно делать при помощи указания абсолютных или относительных путей. Пути можно подключить в область видимости оператором use, поэтому вы можете пользоваться более короткими путями для многократного использования элементов в области видимости. Код модуля по умолчанию является приватным, но можно сделать определения публичными, добавив ключевое слово pub.

В следующей главе мы познакомим вас с некоторыми коллекциями (особыми структурами данных) представленными в стандартной библиотеке. Завершив их изучение вы сможете использовать их в своём аккуратно организованном коде.