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

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

Например, давайте начнём с кода листинга 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, как показано в листинге 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:

Файл: 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.

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