Учебник Rust для начинающих
Rust — компилируемый системный язык, который даёт скорость C++ и при этом не позволяет выстрелить себе в ногу: ошибки работы с памятью он ловит на этапе компиляции, а не в продакшене. Достигается это без сборщика мусора — за счёт уникальной системы владения (ownership). Именно она делает Rust одновременно безопасным и быстрым, и именно из-за неё язык считают сложным.
Этот курс рассчитан на тех, кто уже писал код на любом языке. Мы не тратим время на «что такое цикл», зато подробно, с аналогиями, разбираем то, чего нет в других языках: владение, заимствование, время жизни ссылок. Затем строим на этом фундаменте типы и структуры, сопоставление с образцом, надёжную обработку ошибок без null и исключений, дженерики и трейты, коллекции и инструменты cargo. К концу вы будете читать и писать идиоматичный Rust и понимать, почему компилятор ругается — и почему он прав.
Курс «Rust» состоит из 6 разделов и 24 уроков: Введение в Rust, Владение — ядро Rust, Типы и структуры данных, Сопоставление с образцом и обработка ошибок, Обобщения, трейты и коллекции и Практика и инструменты. Уроки идут по порядку — от основ к более сложным темам, в каждом есть объяснение с примерами, а в конце — вопросы для самопроверки. К урокам привязаны задачи с автоматической проверкой: прочитали тему — сразу закрепили её кодом.
Программа курса
1 Введение в Rust
- Зачем нужен Rust
Чем Rust отличается от C++ и языков со сборщиком мусора: безопасность памяти на этапе компиляции, скорость без рантайма и где применяют язык.
- Установка и cargo
Установка Rust через rustup и работа с cargo: cargo new, build, run, check, структура проекта и манифест Cargo.toml.
- Первая программа и println!
Структура программы на Rust: функция main, макрос println! с восклицательным знаком, подстановка значений через {} и форматирование вывода.
- Переменные, mut и типы
Неизменяемость по умолчанию в Rust, ключевое слово mut, затенение переменных (shadowing) и базовые типы: целые, дробные, bool, char.
- Зачем нужен Rust
2 Владение — ядро Rust
- Что такое владение
Система владения в Rust на наглядной аналогии: каждое значение имеет одного владельца, память освобождается при выходе из области видимости, без сборщика мусора.
- Перемещение и копирование
Семантика перемещения (move) для типов из кучи и копирования (Copy) для простых типов в Rust: почему String перемещается, а числа копируются, и зачем нужен clone.
- Заимствование: & и &mut
Заимствование в Rust через ссылки: неизменяемые & и изменяемые &mut, золотое правило borrow checker (много читателей или один писатель) и запрет висячих ссылок.
- Срезы и время жизни
Срезы как ссылки на часть коллекции, разница между String и &str, и мягкое введение в lifetimes — как Rust гарантирует, что ссылка не переживёт свои данные.
- Что такое владение
3 Типы и структуры данных
- Кортежи и массивы
Кортежи для группировки значений разных типов и деструктуризации, массивы фиксированной длины [T; N] и безопасная индексация с проверкой выхода за границу.
- Векторы (Vec)
Динамический массив Vec в Rust: создание через Vec::new и vec!, добавление push, индексация и безопасный get, итерация по ссылкам и изменение элементов.
- Структуры и методы
Структуры в Rust: объявление полей, создание экземпляров, методы в блоке impl с &self и &mut self, ассоциированные функции-конструкторы и кортежные структуры.
- Перечисления и Option
Перечисления (enum) в Rust с вариантами, несущими данные, и тип Option как безопасная замена null: Some/None и обязательная обработка отсутствия значения.
- Кортежи и массивы
4 Сопоставление с образцом и обработка ошибок
- Сопоставление с образцом: match
Оператор match в Rust: сопоставление с образцом, обязательная исчерпывающность всех случаев, извлечение данных из вариантов, диапазоны, альтернативы и охранные условия.
- if let и while let
Компактные формы сопоставления с образцом в Rust: if let для одного интересующего варианта, if let else как развилка и while let для циклов до несовпадения образца.
- Result и оператор ?
Обработка ошибок в Rust через Result<T, E>: Ok и Err как обычные значения вместо исключений и оператор ? для лаконичного пробрасывания ошибок наверх.
- panic! против Result
Когда в Rust использовать panic! для непоправимых ошибок, а когда возвращать Result для восстановимых сбоев; роль unwrap и expect как управляемой паники.
- Сопоставление с образцом: match
5 Обобщения, трейты и коллекции
- Обобщения (generics)
Дженерики в Rust: обобщённые функции и структуры с параметрами-типами <T>, ограничения типов (trait bounds) и мономорфизация как абстракция нулевой стоимости.
- Трейты (traits)
Трейты как интерфейсы Rust: объявление и реализация поведения через impl Trait for Тип, дефолтные методы, трейты как ограничения и автоматический #[derive].
- Коллекция HashMap
Хеш-таблица HashMap в Rust: вставка insert, доступ через get с Option, перебор пар ключ-значение и идиома entry().or_insert() для счётчиков.
- Замыкания и итераторы
Замыкания как анонимные функции с захватом окружения и итераторы в Rust: ленивые цепочки map, filter, collect и sum для декларативной обработки данных.
- Обобщения (generics)
6 Практика и инструменты
- Модули и организация кода
Организация кода в Rust: крейты и модули через mod, видимость pub (приватно по умолчанию), сокращение путей через use и разнесение модулей по файлам.
- Зависимости и crates.io
Подключение сторонних библиотек в Rust: реестр crates.io, добавление зависимостей через cargo add и Cargo.toml, семантическое версионирование и Cargo.lock.
- Тестирование: cargo test
Встроенное тестирование в Rust: функции с атрибутом #[test], макросы assert_eq! и assert!, запуск через cargo test, модуль #[cfg(test)] и проверка паники #[should_panic].
- Умные указатели и что дальше
Обзор умных указателей Box (значение в куче, рекурсивные типы) и Rc (несколько владельцев через счётчик ссылок) и направления дальнейшего изучения Rust.
- Модули и организация кода