Rust: с нуля до своего органайзера Урок 44 из 50
Модули: отделить логику от запуска
Урок 44. Разделить код на файлы и открывать только нужные имена.
Текст переведён с помощью ИИ.
Предварительно: структуры, методы, органайзер. Начните с копии проекта: этот пример короткий и заменяет src/main.rs, чтобы увидеть границу доступа. Файловое сохранение задач ещё не началось.
Образ и опорная карта
В мастерской есть общий стол и закрытый шкаф с инструментами. На стол выставляют только то, что нужно посетителю; остальное остаётся внутри. Модуль (mod) группирует имена и задаёт границу видимости. pub открывает имя за этой границей. Образ ограничен: приватность в коде помогает строить понятный интерфейс, но не шифрует данные и не защищает компьютер от пользователя.
main → use crate::organizer::Task → открытые Task::new и task.print → скрытые поля. crate обозначает корень текущей единицы компиляции. :: соединяет части пути к имени. use разрешает писать короткое Task вместо полного пути. pub struct Task открывает тип, но его поля id и title без pub остаются закрытыми. Поэтому main может вызвать открытый конструктор и метод, но не может написать task.title = .... Это даёт структуре возможность проверять изменения в своих методах. Self внутри impl Task означает сам тип Task, как в уроке 28.
Сначала один файл
Замените src/main.rs и выполните cargo run. Сообщения Cargo отделены от вывода программы. Новых зависимостей нет.
mod organizer {
pub struct Task {
id: u32,
title: String,
}
impl Task {
pub fn new(id: u32, title: &str) -> Self {
Self {
id,
title: String::from(title),
}
}
pub fn print(&self) {
println!("Задача {}: {}", self.id, self.title);
}
}
}
use crate::organizer::Task;
fn main() {
let task = Task::new(1, "Читать Rust");
task.print();
}
Задача 1: Читать Rust
Затем два файла
Теперь перенесите всё внутри mod organizer { ... } в новый файл src/organizer.rs без внешних фигурных скобок. В начале src/main.rs вместо всего блока поставьте mod organizer;, оставьте use crate::organizer::Task; и fn main(). Точка с запятой после mod organizer сообщает Rust искать тело в отдельном файле. Команда cargo run должна вывести ту же строку. Если получите ошибку private field, вы пытаетесь обратиться к полю из main: используйте открытый метод. Если file not found, проверьте имя и место src/organizer.rs.
main.rs — корень исполняемой части Cargo-пакета, то есть программы, которую запускают. lib.rs может быть корнем отдельной библиотечной части того же пакета: её функции удобно вызывать из других программ и проверять отдельно. В этом упражнении lib.rs не нужен. Простая пара main.rs + organizer.rs уже отделяет запуск от логики. Для большой программы мы перенесём общую логику в библиотеку, когда научимся описывать её открытое поведение.
Вспомните без страницы
- Почему
pub struct Taskне открывает автоматически полеtitle? - Что делает точка с запятой в
mod organizer;? - Чем отличается
main.rsотlib.rs?
Задание
Обязательное. Добавьте открытый метод id(&self) -> u32 и выведите через него Номер: 1; поле id оставьте закрытым. Сделайте это и в варианте с двумя файлами. Проверьте cargo run. Не решайте задачу добавлением pub к самому полю.
Ответы
Показать ответы
Внутри impl Task метод может читать self.id; снаружи вызовите task.id(). При переносе в файл тело метода остаётся внутри src/organizer.rs.
Эталон после попытки
Ниже полный эталон для одного файла. Для двух файлов используйте описанный выше перенос блока модуля.
mod organizer {
pub struct Task {
id: u32,
title: String,
}
impl Task {
pub fn new(id: u32, title: &str) -> Self {
Self {
id,
title: String::from(title),
}
}
pub fn print(&self) {
println!("Задача {}: {}", self.id, self.title);
}
pub fn id(&self) -> u32 {
self.id
}
}
}
use crate::organizer::Task;
fn main() {
let task = Task::new(1, "Читать Rust");
task.print();
println!("Номер: {}", task.id());
}
Задача 1: Читать Rust
Номер: 1
После проверки
Официальное объяснение модулей · разделение по файлам. Если impl ещё незнаком, вернитесь к уроку 28.
Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом
Комментарии (0)
Войдите, чтобы оставить комментарий →
Пока нет комментариев. Будьте первым.