Как подключить модуль из другого файла в Rust: гид для новичков

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как включить модуль из другого файла в Rust: от новичка до уверенного пользователя

Вы когда-нибудь писали код на Rust и вдруг понимали, что ваш main.rs превращается в гигантского монстра на 500 строк? Знакомо? Или, возможно, вы только начинаете изучать Rust и хотите понять, как правильно организовать код, разбив его на несколько файлов. Вопрос "How can I include a module from another file from the same project?" — один из самых популярных на Stack Overflow, и не зря. Модульная система Rust одновременно мощная и... немного неочевидная для новичков.

В этой статье мы разберем всё от А до Я: как создать модуль, как его подключить, какие есть подводные камни и как не наступить на грабли. Поехали!

Почему модули в Rust — это не просто "include"?

Если вы пришли из Python или JavaScript, вы привыкли к import или require. В Rust всё немного иначе. Здесь нет магического "подхвати файл и используй". Вместо этого Rust использует декларативную систему модулей. Вы должны явно сказать компилятору: "Эй, вот этот файл — часть моего проекта, и вот как он называется".

Основное правило, которое нужно запомнить: каждый файл — это модуль, но не каждый модуль — это файл. Звучит как загадка, да? Сейчас разберемся.

Структура проекта: с чего начать

Предположим, у вас есть проект с такой структурой:

my_project/
├── Cargo.toml
├── src/
│   ├── main.rs
│   ├── greetings.rs
│   └── utils/
│       ├── mod.rs
│       └── helpers.rs

Здесь greetings.rs — простой модуль, а utils/ — папка с модулем. Давайте научимся их подключать.

Способ 1: Подключение простого файла-модуля

Самый базовый случай. У вас есть greetings.rs с функцией:

// greetings.rs
pub fn say_hello() {
    println!("Привет из модуля greetings!");
}

Чтобы использовать этот модуль в main.rs, нужно сделать две вещи:

  1. Объявить модуль с помощью ключевого слова mod
  2. Импортировать нужные элементы с помощью use
// main.rs
mod greetings; // объявляем модуль

use greetings::say_hello; // импортируем функцию

fn main() {
    say_hello(); // используем
}

Вот и всё! Rust автоматически ищет файл greetings.rs в той же папке, где лежит main.rs. Если файл найден — модуль подключен.

Важно: функция say_hello помечена как pub. Если забыть pub, компилятор скажет, что функция приватная и недоступна извне. Это одна из самых частых ошибок новичков.

Способ 2: Модуль в папке (mod.rs или lib.rs)

Когда ваш проект разрастается, удобно группировать модули в папки. Для этого используется файл mod.rs внутри папки. Он служит "точкой входа" в модуль.

Создадим папку utils/ и внутри неё mod.rs:

// utils/mod.rs
pub mod helpers; // объявляем вложенный модуль

Теперь создадим helpers.rs:

// utils/helpers.rs
pub fn do_something() {
    println!("Делаем что-то полезное");
}

В main.rs подключаем так:

// main.rs
mod utils; // объявляем модуль utils (ищет utils/mod.rs)

use utils::helpers::do_something;

fn main() {
    do_something();
}

Обратите внимание: mod utils; говорит Rust искать utils/mod.rs или utils.rs. Если найдёт mod.rs — отлично, если utils.rs — тоже подойдёт. Но нельзя иметь оба файла одновременно — компилятор запутается.

Способ 3: Современный подход (Rust 2018+)

Начиная с Rust 2018, вы можете использовать путь к модулю без mod.rs. Вместо utils/mod.rs можно создать utils.rs и папку utils/ рядом. Это называется "модуль с вложенными подмодулями".

Структура будет такой:

src/
├── main.rs
├── utils.rs
└── utils/
    └── helpers.rs

В utils.rs пишем:

// utils.rs
pub mod helpers;

А в helpers.rs — тот же код. В main.rs ничего не меняется:

mod utils;
use utils::helpers::do_something;

Какой способ выбрать? Лично я рекомендую второй (с mod.rs), если вы новичок — он более наглядный и явный. Но оба работают отлично.

Частые ошибки и как их избежать

Давайте разберём топ-3 граблей, на которые наступают почти все:

1. "Модуль не найден" (file not found for module)

Вы написали mod my_module;, а Rust пишет: "не могу найти файл". Причины:

  • Файл называется my_module.rs, а не myModule.rs (регистр важен!)
  • Файл лежит не в той папке. Для mod my_module; в main.rs файл должен быть рядом: src/my_module.rs
  • Вы случайно создали my_module.rs и my_module/mod.rs одновременно — удалите один из них.

2. "Функция приватная" (function is private)

Вы импортировали модуль, но не можете вызвать функцию. Решение: добавьте pub перед функцией, структурой или полем.

// Неправильно
fn secret() {} // приватная

// Правильно
pub fn secret() {} // публичная

3. "Путь не найден" (unresolved import)

Вы написали use my_module::my_function;, а Rust не понимает, где my_function. Проверьте:

  • Правильно ли объявлен модуль через mod?
  • Не забыли ли pub у самой функции?
  • Правильно ли написан путь? Если модуль вложен, путь должен быть полным: utils::helpers::do_something.

Продвинутый пример: модули в библиотеке (lib.rs)

Блоги

Рекомендаций по книгам