Содержание курса
Модуль 1. Введение: от джуна к продуктивному миддлу
6 уроков
1.
Чем миддл на Rust отличается от джуна: не только «больше кода»
↗
2.
Что мы считаем пройденным: краткая ревизия базы Rust
↗
3.
Ещё одна ревизия: владение, заимствование и матчинг на одном…
↗
4.
Как устроен этот курс и как с ним работать
↗
5.
Обновляем инструменты: rustup, стабильный компилятор, clippy…
↗
6.
С чего начать, если вы пришли не из курса «Rust для джунов»
↗
Модуль 2. Углублённое владение и заимствование
8 уроков
1.
Владение ещё раз, но глубже: кто и когда освобождает память
↗
2.
Перемещение (move) против копирования: Copy и Clone в деталях
↗
3.
Заимствование под микроскопом: правила borrow checker
↗
4.
Изменяемое и неизменяемое заимствование: почему нельзя смешивать
↗
5.
Non-Lexical Lifetimes: почему заимствование заканчивается…
↗
6.
Заимствование полей структуры по отдельности
↗
7.
Частые ошибки borrow checker и как их читать
↗
8.
Reborrow: как ссылка на ссылку упрощает жизнь
↗
Модуль 3. Времена жизни (lifetimes)
9 уроков
1.
Зачем нужны времена жизни: проблема висячих ссылок
↗
2.
Первая аннотация времени жизни: синтаксис 'a
↗
3.
Времена жизни в сигнатурах функций
↗
4.
Правила элизии: почему аннотации часто не нужны
↗
5.
Несколько параметров времени жизни в одной функции
↗
6.
Времена жизни в структурах: храним ссылку внутри
↗
7.
Времена жизни в методах и блоке impl
↗
8.
Время жизни 'static: что это и когда уместно
↗
9.
Связь времён жизни и заимствования: собираем картину целиком
↗
Модуль 4. Замыкания (closures)
8 уроков
1.
Что такое замыкание и чем оно отличается от функции
↗
2.
Захват переменных из окружения: по ссылке и по значению
↗
3.
Ключевое слово move: забираем владение в замыкание
↗
4.
Трейты Fn, FnMut и FnOnce: три способа вызвать замыкание
↗
5.
Передаём замыкание в функцию: границы по Fn-трейтам
↗
6.
Возвращаем замыкание: impl Fn и Box
↗
7.
Функции как значения: указатели на функции fn
↗
8.
Практика: собственный кэширующий обёртка на замыкании
↗
Модуль 5. Итераторы: глубокое погружение
11 уроков
1.
Трейт Iterator и метод next: как работает цикл под капотом
↗
2.
Ленивость итераторов: почему без collect ничего не происходит
↗
3.
Адаптеры map, filter, take, skip и их комбинирование
↗
4.
Потребляющие методы: sum, count, fold, reduce
↗
5.
Метод collect и вывод типа через turbofish
↗
6.
Собираем в разные коллекции: Vec, HashMap, String
↗
7.
enumerate, zip, chain, rev и flat_map
↗
8.
Метод filter_map и работа с Option в цепочке
↗
9.
Реализуем собственный итератор через impl Iterator
↗
10.
IntoIterator: как for понимает разные коллекции
↗
11.
Крейт itertools: полезные адаптеры сверх стандартных
↗
Модуль 6. Продвинутые трейты
8 уроков
1.
Трейты как контракт: вспоминаем и идём дальше
↗
2.
Реализации по умолчанию и переопределение методов
↗
3.
Границы трейтов на дженериках и синтаксис where
↗
4.
Ассоциированные типы против параметров-типов
↗
5.
Супертрейты: один трейт требует другого
↗
6.
Orphan rule: почему нельзя реализовать чужой трейт для чужого…
↗
7.
Паттерн newtype: обходим orphan rule
↗
8.
Маркерные трейты и что они значат
↗
Модуль 7. Диспетчеризация и трейт-объекты
7 уроков
1.
Статическая диспетчеризация и мономорфизация
↗
2.
Динамическая диспетчеризация: трейт-объекты dyn Trait
↗
3.
Box: храним разные типы за одним интерфейсом
↗
4.
&dyn Trait и vtable: как это работает внутри
↗
5.
Object safety: почему не любой трейт можно сделать dyn
↗
6.
Статика против динамики: производительность и гибкость
↗
7.
Вектор трейт-объектов: гетерогенные коллекции
↗
Модуль 8. Ключевые трейты стандартной библиотеки
9 уроков
1.
Display и Debug: два способа показать значение
↗
2.
From и Into: идиоматичные преобразования типов
↗
3.
TryFrom и TryInto: преобразования, которые могут не удаться
↗
4.
Перегрузка операторов: трейты Add, Mul и другие
↗
5.
PartialEq, Eq и сравнение на равенство
↗
6.
PartialOrd, Ord и упорядочивание значений
↗
7.
Трейт Default: разумные значения по умолчанию
↗
8.
Deref и Deref coercion: почему &Box; ведёт себя как T
↗
9.
Трейт Drop: свой код при освобождении значения
↗
Модуль 9. Дженерики: продвинутый уровень
8 уроков
1.
Дженерики ещё раз: параметры типов в функциях и структурах
↗
2.
Мономорфизация: как дженерики превращаются в конкретный код
↗
3.
Границы трейтов на дженериках: комбинируем требования
↗
4.
Дженерики с несколькими параметрами и where-блоки
↗
5.
Const-дженерики: параметризация по значениям
↗
6.
Массивы фиксированного размера через const-дженерики
↗
7.
Ассоциированные константы в трейтах
↗
8.
Фантомные типы: PhantomData и типовые состояния
↗
Модуль 10. Обработка ошибок по-взрослому
10 уроков
1.
Вспоминаем Result и оператор ?
↗
2.
Оператор ? с автоматической конверсией через From
↗
3.
Свой тип ошибки как перечисление
↗
4.
Реализуем трейт std::error::Error для своей ошибки
↗
5.
Box: универсальный тип для любой ошибки
↗
6.
Крейт thiserror: свои ошибки без шаблонного кода
↗
7.
Крейт anyhow: удобные ошибки в приложениях
↗
8.
thiserror против anyhow: библиотека или приложение
↗
9.
Добавляем контекст к ошибкам с помощью context
↗
10.
Паника против Result: когда паника оправдана
↗
Модуль 11. Умные указатели
9 уроков
1.
Что такое умный указатель и зачем он нужен
↗
2.
Box: значение в куче и рекурсивные типы
↗
3.
Rc: разделяемое владение через подсчёт ссылок
↗
4.
Внутренняя изменяемость: почему нужен RefCell
↗
5.
RefCell: проверка заимствования во время выполнения
↗
6.
Комбинация Rc>: разделяемое изменяемое состояние
↗
7.
Циклы ссылок и утечки памяти
↗
8.
Weak: слабые ссылки против циклов
↗
9.
Cow: клонирование только при необходимости
↗
Модуль 12. Коллекции: глубокое погружение
8 уроков
1.
Vec ещё раз: ёмкость, реаллокация и производительность
↗
2.
VecDeque: очередь с двух концов
↗
3.
HashMap глубже: хеширование и entry API
↗
4.
HashSet: множества и операции над ними
↗
5.
BTreeMap и BTreeSet: упорядоченные коллекции
↗
6.
BinaryHeap: приоритетная очередь
↗
7.
Свой ключ для HashMap: трейты Hash и Eq
↗
8.
Выбор коллекции: сравнительная таблица и критерии
↗
Модуль 13. Модули, крейты и организация проекта
8 уроков
1.
Система модулей: mod, pub и дерево модулей
↗
2.
Пути к элементам: use, self, super и crate
↗
3.
Разделяем код на файлы и папки модулей
↗
4.
Библиотечные и бинарные крейты в одном пакете
↗
5.
Cargo.toml изнутри: зависимости, features и профили
↗
6.
Workspace: несколько крейтов в одном репозитории
↗
7.
Условная компиляция: cfg и feature-флаги
↗
8.
Публикация крейта на crates.io и семантическое версионирование
↗
Модуль 14. Тестирование: глубокое погружение
10 уроков
1.
Юнит-тесты и модуль #[cfg(test)] ещё раз
↗
2.
Организация тестов: assert-макросы и структура теста
↗
3.
Атрибут #[should_panic] и проверка паник
↗
4.
Тесты, возвращающие Result, и оператор ?
↗
5.
Интеграционные тесты в папке tests
↗
6.
Doc-тесты: примеры в документации как тесты
↗
7.
Фикстуры и вспомогательные функции для тестов
↗
8.
Property-based тестирование с proptest
↗
9.
Мокирование зависимостей: паттерны и крейт mockall
↗
10.
Бенчмарки с criterion: измеряем производительность
↗
Модуль 15. Сериализация с serde
8 уроков
1.
Зачем нужна сериализация и что умеет serde
↗
2.
Подключаем serde и serde_json через cargo add
↗
3.
Derive Serialize и Deserialize для своих структур
↗
4.
Работа с JSON: from_str, to_string и to_string_pretty
↗
5.
Атрибуты serde: rename, default, skip
↗
6.
Вложенные структуры, перечисления и опциональные поля
↗
7.
Обработка ошибок сериализации и невалидного JSON
↗
8.
Динамический JSON через serde_json::Value
↗
Модуль 16. Приложения командной строки с clap
7 уроков
1.
Аргументы командной строки: env::args и его пределы
↗
2.
Подключаем clap и derive-подход
↗
3.
Позиционные аргументы, флаги и опции
↗
4.
Значения по умолчанию, обязательные и опциональные аргументы
↗
5.
Подкоманды: строим CLI как git
↗
6.
Автоматический help, версия и валидация ввода
↗
7.
Чтение из stdin и работа с файлами через аргументы
↗
Модуль 17. Конкурентность: потоки и разделяемое состояние
11 уроков
1.
Потоки в Rust: thread::spawn и join
↗
2.
Передача владения в поток через move
↗
3.
Send и Sync: как компилятор гарантирует потокобезопасность
↗
4.
Каналы mpsc: обмен сообщениями между потоками
↗
5.
Несколько отправителей и паттерн producer-consumer
↗
6.
Разделяемое состояние: Arc для многопоточного владения
↗
7.
Mutex: взаимное исключение и защита данных
↗
8.
RwLock: много читателей или один писатель
↗
9.
Scoped threads: потоки, заимствующие стек
↗
10.
Атомики: Atomic-типы и порядок памяти базово
↗
11.
Параллелизм данных с rayon: par_iter
↗
Модуль 18. Введение в асинхронность
8 уроков
1.
Зачем нужен async: конкурентность без потока на задачу
↗
2.
Future: значение, которое будет готово позже
↗
3.
async и await: синтаксис и что происходит на самом деле
↗
4.
Почему future ленивы и нужен исполнитель (runtime)
↗
5.
Подключаем tokio и запускаем первую async-функцию
↗
6.
Параллельные задачи: tokio::spawn и join!
↗
7.
Асинхронный HTTP-запрос с reqwest
↗
8.
Async против потоков: когда что выбирать
↗
Модуль 19. Декларативные макросы
6 уроков
1.
Зачем нужны макросы и чем они отличаются от функций
↗
2.
Первый макрос через macro_rules!
↗
3.
Метапеременные и фрагменты: expr, ident, ty и другие
↗
4.
Повторения в макросах: $(...)* и разделители
↗
5.
Несколько правил в одном макросе и сопоставление
↗
6.
Гигиена макросов и типичные подводные камни
↗
Модуль 20. Итоговый проект: CLI-менеджер задач
8 уроков
1.
Проект: постановка задачи и архитектура CLI-менеджера задач
↗
2.
Модель данных и типы ошибок проекта
↗
3.
Хранение задач в JSON через serde
↗
4.
Интерфейс командной строки на clap: добавление и просмотр задач
↗
5.
Редактирование, удаление и фильтрация задач
↗
6.
Покрываем проект тестами: юнит и интеграционные
↗
7.
Рефакторинг, обработка ошибок и финальная полировка
↗
8.
Куда двигаться дальше: анонс курса «Rust для сеньоров»
↗