Rust Roadmap 2025: с нуля до продакшена за 6 месяцев

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Rust в 2025: почему именно сейчас?

За последние три года Rust совершил настоящий прорыв. Язык, который изначально казался "сложным и нишевым", сегодня используют в ядре Linux, в браузерах (Firefox, частично Chromium), в инструментах для DevOps (ripgrep, fd, bat) и даже в веб-разработке. В 2025 году Rust — это не просто "ещё один язык", а инструмент номер один для написания безопасного, быстрого и надёжного кода.

Но есть одна проблема: порог входа. Rust славится своим borrow checker'ом, временами жизни (lifetimes) и строгой системой типов. Многие новички бросают обучение на второй неделе, уткнувшись в ошибки компилятора.

Эта статья — roadmap по изучению Rust в 2025 году. Я расписал порядок тем, дал реальные примеры кода и объяснил, что учить обязательно, а что можно оставить на потом. Поехали!

Этап 1: Фундамент (Недели 1–2)

1.1 Установка и первая программа

Начнём с установки через rustup — официальный установщик. Он управляет версиями компилятора и тулчейна.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustc --version
cargo --version

Ваш первый файл main.rs:

fn main() {
    println!("Привет, мир Rust 2025!");
}

Компилируем: rustc main.rs && ./main. Но лучше сразу привыкать к Cargo — менеджеру пакетов и сборщику:

cargo new my_first_project
cd my_first_project
cargo run

1.2 Переменные, типы, управляющие конструкции

Rust строго типизирован, но компилятор часто выводит типы сам. Главное отличие от Python или JavaScript — переменные по умолчанию неизменяемы (immutable).

fn main() {
    let x = 5;          // immutable
    let mut y = 10;     // mutable
    y += 5;

    let name = "Rust";
    let year: u32 = 2025;

    if year > 2024 {
        println!("{} — будущее уже здесь!", name);
    }

    for i in 0..5 {
        println!("Счёт: {}", i);
    }
}

1.3 Владение (Ownership) — краеугольный камень

Это то, что пугает новичков больше всего. Но без понимания ownership вы не напишете ни одного реального проекта. Суть: у каждого значения в Rust есть ровно один владелец. Когда владелец выходит из области видимости, память освобождается.

fn main() {
    let s1 = String::from("hello");
    let s2 = s1; // владение перемещается в s2

    // println!("{}", s1); // ОШИБКА! s1 больше не владеет строкой
    println!("{}", s2); // ок
}

Если нужно передать данные без потери владения, используем ссылку (reference):

fn main() {
    let s = String::from("Rust");
    let len = calculate_length(&s); // заимствуем
    println!("Длина '{}' = {}", s, len); // s всё ещё доступна
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

Этап 2: Углубление (Недели 3–5)

2.1 Структуры, перечисления и pattern matching

Rust — не ООП-язык в классическом смысле, но структуры и трейты (traits) покрывают 90% потребностей.

struct User {
    username: String,
    email: String,
    active: bool,
}

enum Status {
    Active,
    Inactive,
    Banned { reason: String },
}

fn check_status(status: Status) {
    match status {
        Status::Active => println!("Пользователь активен"),
        Status::Inactive => println!("Неактивен"),
        Status::Banned { reason } => println!("Забанен: {}", reason),
    }
}

2.2 Обработка ошибок: Option и Result

В Rust нет исключений (exceptions). Вместо них — элегантные Result<T, E> и Option<T>. Забудьте про try/except — теперь вы используете match или ?.

fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("Деление на ноль!".to_string())
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10.0, 0.0) {
        Ok(result) => println!("Результат: {}", result),
        Err(e) => println!("Ошибка: {}", e),
    }

    // Или с оператором '?' (только в функциях, возвращающих Result)
    fn compute() -> Result<f64, String> {
        let res = divide(10.0, 2.0)?;
        Ok(res * 2.0)
    }
}

2.3 Коллекции: Vec, HashMap, итераторы

Векторы и хеш-таблицы — база. Итераторы в Rust ленивые и невероятно мощные.

fn main() {
    let mut vec = vec![1, 2, 3, 4, 5];
    vec.push(6);

    let sum: i32 = vec.iter().sum();
    println!("Сумма: {}", sum);

    let squared: Vec<i32> = vec.iter().map(|x| x * x).collect();
    println!("Квадраты: {:?}", squared);

    use std::collections::HashMap;
    let mut map = HashMap::new();
    map.insert("Rust", 2025);
    map.insert("PythonLib", 2024);
}

Этап 3: Продвинутые концепции (Недели 6–8)

3.1 Времена жизни (Lifetimes)

Самая сложная тема для новичков. Аннотации 'a говорят компилятору: "эта ссылка живёт как минимум столько же, сколько та".

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let s1 = String::from("длинная строка");
    let s2 = "короткая";
    let result = longest(&s1, s2);
    println!("Длиннейшая: {}", result);
}

Совет: Не пытайтесь выучить lifetimes за один день. Просто запомните шаблоны: &'a str для строк, &'a mut T для изменяемых ссылок. Компилятор сам подскажет, где нужны аннотации.

3.2 Трейты (Traits) и обобщения (Generics)

Трейты — это интерфейсы Rust. Они позволяют определять общее поведение для разных типов.

trait Summary {
    fn summarize(&self) ->                

Блоги

Рекомендаций по книгам