Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Справочная карточка

Руководство по выбору паттерна

Нужна безопасность типов для примитивов?
└── Паттерн newtype (гл. 3)

Нужно обеспечить состояния на этапе компиляции?
└── Паттерн type-state (гл. 3)

Нужен «тег» без данных во время выполнения?
└── PhantomData (гл. 4)

Нужно разорвать циклы ссылок Rc/Arc?
└── Weak<T> / sync::Weak<T> (гл. 9)

Нужно дождаться условия без активного опроса?
└── Condvar + Mutex (гл. 6)

Нужно обрабатывать «один из N типов»?
├── Известное закрытое множество → перечисление (enum)
├── Открытое множество, горячий путь → обобщения
├── Открытое множество, холодный путь → dyn Trait
└── Полностью неизвестные типы → Any + TypeId (гл. 2)

Нужно разделяемое состояние между потоками?
├── Простой счётчик или флаг → атомарные типы
├── Короткая критическая секция → Mutex
├── Много чтений → RwLock
├── Ленивая однократная инициализация → OnceLock / LazyLock (гл. 6)
└── Сложное состояние → актор + каналы

Нужно распараллелить вычисления?
├── Обработка коллекций → rayon::par_iter
├── Фоновая задача → thread::spawn
└── Заимствование локальных данных → thread::scope

Нужен асинхронный ввод-вывод или конкурентная работа с сетью?
├── Базовый уровень → tokio + async/await (гл. 16)
└── Продвинутый (потоки, middleware) → см. Async Rust Training

Нужна обработка ошибок?
├── Библиотека → thiserror (#[derive(Error)])
└── Приложение → anyhow (Result<T>)

Нужно запретить перемещение значения?
└── Pin<T> (гл. 9): обязателен для Future и самоссылающихся типов

Шпаргалка по границам трейтов

ОграничениеЗначение
T: CloneМожно дублировать
T: SendМожно передать в другой поток
T: Sync&T можно разделять между потоками
T: 'staticНе содержит заимствованных ссылок с ограниченным временем жизни
T: SizedРазмер известен на этапе компиляции (по умолчанию)
T: ?SizedРазмер может быть неизвестен ([T], dyn Trait)
T: UnpinБезопасно перемещать после закрепления (pin)
T: DefaultЕсть значение по умолчанию
T: Into<U>Можно преобразовать в U
T: AsRef<U>Можно заимствовать как &U
T: Deref<Target = U>Автоматически разыменовывается в &U
F: Fn(A) -> BВызываемый, заимствует состояние неизменяемо
F: FnMut(A) -> BВызываемый, может изменять состояние
F: FnOnce(A) -> BВызываемый ровно один раз, может потребить состояние

Правила elision времён жизни

Компилятор автоматически вставляет времена жизни в трёх случаях, чтобы вам не приходилось делать это вручную:

#![allow(unused)]
fn main() {
// Правило 1: каждый параметр-ссылка получает собственное время жизни
// fn foo(x: &str, y: &str)  →  fn foo<'a, 'b>(x: &'a str, y: &'b str)

// Правило 2: если есть ровно ОДНО входное время жизни, оно используется для всех выходных
// fn foo(x: &str) -> &str   →  fn foo<'a>(x: &'a str) -> &'a str

// Правило 3: если один из параметров это &self или &mut self, используется его время жизни
// fn foo(&self, x: &str) -> &str  →  fn foo<'a>(&'a self, x: &str) -> &'a str
}

Когда время жизни НУЖНО писать явно:

  • Несколько входных ссылок и ссылка на выходе (компилятор не может угадать, какой вход имеется в виду)
  • Поля структур, которые хранят ссылки: struct Ref<'a> { data: &'a str }
  • Границы 'static, когда нужны данные без заимствованных ссылок

Распространённые производные трейты

#![allow(unused)]
fn main() {
#[derive(
    Debug,          // Форматирование {:?}
    Clone,          // .clone()
    Copy,           // Неявное копирование (только для простых типов)
    PartialEq, Eq,  // Сравнение ==
    PartialOrd, Ord, // Сравнение < > и сортировка
    Hash,           // Ключ HashMap/HashSet
    Default,        // Type::default()
)]
struct MyType { /* ... */ }
}

Краткая справка по видимости модулей

pub           → видим везде
pub(crate)    → видим внутри крейта
pub(super)    → видим родительскому модулю
pub(in path)  → видим внутри конкретного пути
(ничего)      → приватен для текущего модуля и его потомков

Дополнительная литература

РесурсПочему стоит прочитать
Rust Design PatternsКаталог идиоматичных паттернов и антипаттернов
Rust API GuidelinesОфициальный чек-лист для аккуратных публичных API
Rust Atomics and LocksГлубокий разбор примитивов конкурентности от Mara Bos
The RustonomiconОфициальное руководство по unsafe Rust и тёмным углам языка
Error Handling in RustПодробное руководство Andrew Gallant
Jon Gjengset — Crust of Rust seriesГлубокие разборы итераторов, времён жизни, каналов и др.
Effective Rust35 конкретных способов улучшить ваш код на Rust

Конец книги «Паттерны Rust и практические руководства по инженерии»