Мы прошлись по фундаменту языка Rust: от управления памятью (RAII и Box), умных указателей (Rc, Weak, Arc) и внутренней мутабельности (Cell, RefCell, Mutex) до коллекций, итераторов и генераторов кода на макросах.
Настало время соединить все эти элементы в единый практический архитектурный проект!
Мы спроектируем систему PetCare Hub — автоматизированный комплекс управления заботой о питомцах (кошках, собаках, птицах). Система должна отслеживать состояние здоровья, управлять автоматическими кормушками и поилочками, обрабатывать датчики телеметрии в параллельных потоках и расставлять приоритеты экстренным вызовам ветеринара.
В реальном мире животные имеют разный рацион и правила ухода. В Rust мы описываем общее поведение через типаж PetAction.
Так как мы не знаем заранее, сколько кошек или собак зарегистрирует пользователь, мы используем динамическую диспетчеризацию (Trait Objects) в виде Box<dyn PetAction>. Это обеспечивает гибкое хранение разного поведения в едином векторе без необходимости жесткого связывания типов на этапе компиляции.
А для быстрой регистрации новых карточек животных мы используем декларативный макрос pet_profile!.
Исследуйте доменную модель в интерактивных слайдах:
Доменная модель и Trait Objects
Шаг 1/2
1// Шаг 1: Доменная модель и полиморфизм через Trait Objects (dyn PetAction)
2traitPetAction{ 3fnname(&self)-> &str; 4fnperform_care(&self)-> String; 5} 6 7structCat{ 8name: String, 9}1011implPetActionforCat{12fnname(&self)-> &str{&self.name}13fnperform_care(&self)-> String{14format!("Кот {}: выдать порцию сухого корма и запустить автопоилку",self.name)15}16}1718structDog{19name: String,20}2122implPetActionforDog{23fnname(&self)-> &str{&self.name}24fnperform_care(&self)-> String{25format!("Собака {}: выдать влажный корм и открыть умную дверцу в сад",self.name)26}27}2829fnmain(){30// Гетерогенная коллекция питомцев через Box<dyn PetAction>
31letpets: Vec<Box<dynPetAction>>=vec![32Box::new(Cat{name: "Барсик".to_string()}),33Box::new(Dog{name: "Рекс".to_string()}),34];3536println!("--- Автоматический уход за питомцами ---");37forpetin&pets{38println!("{}",pet.perform_care());39}40}41
1. Доменная модель и Trait Objects
Типаж PetAction описывает общий контракт поведения для всех питомцев.
Обертка Box<dyn PetAction> позволяет хранить разные типы животных в одном векторе.
Фоновые потоки отслеживают показатели датчиков температуру и уровня воды. Чтобы безопасно делиться расписанием между потоками кормления и мониторинга, используется комбинация Arc<Mutex<Scheduler>>.
В приюте или дома могут происходить события разной важности. Обычная очередь VecDeque обработала бы плановое кормление кота раньше, чем экстренный сигнал о повышенной температуре у собаки.
Использование BinaryHeap (Max-Кучи) гарантирует, что задача с наивысшим приоритетом (например, priority: 100 — выдача медикаментов) всегда будет обработана первой, независимо от того, когда она попала в очередь!
Вместо выделения временных векторов в куче при поиске тревожных сигналов, мы пишем собственный итератор CriticalAlertsIterator. Он производит отбор критических ситуаций лениво (Lazy Evaluation) «на лету» во время обхода.
Запустите примеры многопоточной синхронизации и кастомного итератора:
Многопоточность, Приоритеты и Итератор
Шаг 1/2
1usestd::cmp::Ordering; 2usestd::collections::BinaryHeap; 3usestd::sync::{Arc,Mutex}; 4usestd::thread; 5 6// Элемент очереди ухода с приоритетом
7#[derive(Eq, PartialEq)] 8structCareTask{ 9priority: u32,10description: String,11}1213implOrdforCareTask{14fncmp(&self,other: &Self)-> Ordering{15self.priority.cmp(&other.priority)// Max-Heap по приоритету
16}17}1819implPartialOrdforCareTask{20fnpartial_cmp(&self,other: &Self)-> Option<Ordering>{21Some(self.cmp(other))22}23}2425fnmain(){26// Многопоточный хаб управления приютом/кормушкой через Arc<Mutex>
27letschedule=Arc::new(Mutex::new(BinaryHeap::new()));2829// Фоновый поток добавляет регулярные кормления
30letsched_clone=Arc::clone(&schedule);31lethandle=thread::spawn(move||{32letmutlock=sched_clone.lock().unwrap();33lock.push(CareTask{priority: 10,description: "Плановое кормление в 18:00".to_string()});34});3536// Главный поток регистрирует срочный прием лекарства
37{38letmutlock=schedule.lock().unwrap();39lock.push(CareTask{priority: 100,description: "СРОЧНО: Выдать инсулин коту Мурзику".to_string()});40}4142handle.join().unwrap();4344println!("--- Выполнение задач ухода по степени важности ---");45letmutlock=schedule.lock().unwrap();46whileletSome(task)=lock.pop(){47println!("Выполняется [Приоритет {}]: {}",task.priority,task.description);48}49}50
1. Многопоточный хаб и Очередь Приоритетов
Arc<Mutex<...>> обеспечивает безопасный доступ к планировщику из параллельных потоков.
BinaryHeap гарантирует, что критические медицинские задачи (приоритет 100) выталкиваются раньше планового кормления.
Проектируя PetCare Hub, мы увидели истинную силу Rust:
Гарантии памяти без GC: Умные указатели Box и Arc контролируют жизненный цикл объектов без паузы на сборку мусора.
Безопасность потоков (Data Race Freedom): Компилятор запретит передавать данные в потоки без реализации типажей Send и Sync.
Нулевая стоимость абстракций: Итераторы и макросы позволяют писать высокоуровневый код, который компилируется в максимально быстрый машинно-ориентированный код.