Модули позволяют организовать код - определения функций, структур, трейтов, перечислений и т.д. в функциональные группы. Затем эти группы можно повторно использовать в различных частях программы как единое целое. Кроме того, модули позволяют управлять приватностью отдельных функциональных блоков, определять, какой функционал будет доступен вне модуля, а какой нет.
Определение начинается с ключевого слова mod, за которым следует имя модуля и в фигурных скобках функционал модуля:
mod имя_модуля{ // функционал модуля }
Функционал модуля представляют функции, структуры, перечисления, трейты, перечисления, определения методов, которые в нем определены. Например, определение простейшего модуля:
mod my_module{ // определяем модуль pub fn test(){ // определяем публичную функцию - с атрибутом pub println! ("Hello from my_module"); } }
В данном случае модуль называется my_module
. В этом модуле определена одна функция - test()
, которая выводит строку на консоль.
Определение этой функции начинается с ключевого слова pub, которое позволяет использовать данную функцию вне модуля.
Для обращения к функционалу модуля применяется следующий синтаксис:
имя_модуля::функциональность
После имени модуля через два двоеточия :: указывается функциональность (например, функция), к которой происходит обращение.
Например, вызовем из выше определенного модуля функцию test()
:
mod my_module{ // определяем модуль pub fn test(){ // определяем публичную функцию - с атрибутом pub println! ("Hello from my_module"); } } fn main(){ my_module::test(); // обращаемся к функции из модуля }
Обращение к функции из модуля происходит также, как в общем случае, только названием функции указывается имя модуля и оператор ::
.
Кроме общей организации функционала в общие группы модули позволяют установить приватность и публичность для вложенного функционала.
По умолчанию весь функционал модуля является приватным и доступен только внутри самого. Например, возьмем предыдущий пример и уберем в нем
ключевое слово pub
из определения функции:
mod my_module{ fn test(){ println!("Hello from my_module"); } } fn main(){ my_module::test(); }
При компиляции такой программы мы получим ошибку "function `test` is private"
:
Такую функцию мы можем использовать только внутри ее модуля.
Если какой-то функционал нужно использовать вне модуля, то в его определении необходимо использовать ключевое слово pub, которое делает соответствующий функционал видимым вне его модуля:
mod my_module{ fn private_test(){ println!("Private test"); } pub fn public_test(){ println!("Public test"); private_test(); } } fn main(){ my_module::public_test(); // my_module::private_test(); // !Ошибка - функция private_test приватная }
Здесь в модуле my_module определены две функции. Функция private_test приватная и может использоваться только внутри этого модуля. Например, мы можем вызвать ее в другой функции - public_test. А функция public_test - публичная и может вызываться вне модуля, например, в функции main.
При определении структур, их полей и методов следует учитывать, что они также по умолчанию приватные. Поэтому, если мы хотим, чтобы они были доступны вне модуля, также к ним необходимо применять ключевое слово pub:
mod my_module{ pub struct Person { pub name: String, pub age: u8 } impl Person{ pub fn display(&self){ println!("Name: {} Age: {}", &self.name, &self.age); } } } fn main(){ let tom = my_module::Person{ name: String::from("Tom"), age: 36 }; tom.display(); }
При обращении к структурам из другого модуля, перед их названием также указывается название модуля и оператор ::
.
Особенностью перечислений является то, что перед их константами не надо указывать слово pub, чтобы сделать их доступными вне модуля:
mod my_module{ pub enum DayTime{ Morning, Afternoon, Evening, Night } } fn main(){ let morning = my_module::DayTime::Morning; if let morning = my_module::DayTime::Morning{ println!("Good Morning!"); } else{ println!("Hello!"); } }