Rust в 2025 году: новые возможности на практике

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

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

Начать курс

Rust в 2025 году: что нового? Практические возможности

2025 год стал знаковым для экосистемы Rust. Язык, который уже завоевал сердца системных программистов, веб-разработчиков и создателей инструментов командной строки, получил ряд долгожданных обновлений. Если в 2023-2024 годах основное внимание уделялось стабилизации и улучшению инструментария, то в 2025-м акцент сместился на радикальное упрощение написания сложного кода и повышение производительности без потери безопасности.

В этой статье мы разберем три ключевых нововведения, которые уже доступны в стабильной версии Rust 2025, и покажем их на конкретных примерах. Если вы следите за развитием Rust или только начинаете с ним знакомиться, этот материал поможет вам быстро войти в курс дела.

1. Асинхронные итераторы: async gen и async for

Одной из самых горячих тем в 2025 году стала стабилизация асинхронных генераторов и итераторов. Раньше написание асинхронного итератора требовало ручной реализации трейта Stream или использования сторонних крейтов. Теперь всё стало проще и элегантнее.

Ключевое нововведение — ключевое слово async в сочетании с gen и возможность использовать async for в циклах. Это позволяет писать код, который асинхронно генерирует и потребляет последовательности данных, не блокируя поток выполнения.

Пример: Асинхронный генератор чисел Фибоначчи

use std::time::Duration;
use tokio::time::sleep;

// Асинхронный генератор, который "выдает" числа Фибоначчи с задержкой
async fn async_fibonacci(limit: u32) -> impl AsyncIterator<Item = u64> {
    async gen {
        let (mut a, mut b) = (0, 1);
        for _ in 0..limit {
            sleep(Duration::from_millis(100)).await; // Имитация асинхронной работы
            yield b; // Ключевое слово yield
            let next = a + b;
            a = b;
            b = next;
        }
    }
}

#[tokio::main]
async fn main() {
    println!("Асинхронные числа Фибоначчи (первые 10):");
    // Используем async for для потребления
    async for number in async_fibonacci(10) {
        println!("Получено: {}", number);
    }
    println!("Готово!");
}

Что это даёт на практике?

  • Упрощение кода: Больше не нужно писать сложные комбинаторы из крейта futures.
  • Читаемость: Код выглядит как обычный синхронный генератор, но работает асинхронно.
  • Производительность: Компилятор оптимизирует такие конструкции, сводя накладные расходы к минимуму.

Это особенно полезно для обработки потоков данных из сети, чтения больших файлов или работы с WebSocket-соединениями.

2. Улучшенный borrow checker: Polonius стабилизирован

Borrow checker — это "душа" Rust, отвечающая за безопасность памяти без сборщика мусора. Однако новички (да и опытные разработчики) часто сталкивались с ситуациями, когда компилятор отвергал абсолютно безопасный код. В 2025 году модель заимствования Polonius наконец-то стала частью стабильного компилятора.

Polonius использует более точный анализ потока данных, что позволяет компилятору "понимать" более сложные паттерны работы с ссылками.

Пример: Проблема "двух мутабельных заимствований"

Раньше такой код не компилировался:

fn push_and_pop(vec: &mut Vec<i32>) -> &i32 {
    vec.push(1);
    // Ошибка: нельзя взять мутабельную ссылку (push) и затем иммутабельную (pop)
    let last = vec.last().unwrap();
    last
}

В Rust 2025 с Polonius это работает! Компилятор видит, что после push мутабельная ссылка больше не используется, и разрешает взять иммутабельную ссылку на последний элемент. Вот как это выглядит:

fn push_and_pop(vec: &mut Vec<i32>) -> &i32 {
    vec.push(1); // Мутабельное заимствование заканчивается здесь
    // Polonius понимает, что push больше не нужен
    let last = vec.last().unwrap(); // Иммутабельное заимствование
    last
}

fn main() {
    let mut my_vec = vec![5, 10];
    let result = push_and_pop(&mut my_vec);
    println!("Последний элемент: {}", result);
    // my_vec теперь [5, 10, 1]
}

Что это даёт на практике?

  • Меньше "борьбы с компилятором": Код, который был логически верен, теперь компилируется без лишних clone() или unsafe.
  • Более гибкие API: Можно писать более сложные функции, работающие с внутренними структурами данных.
  • Повышение производительности: Меньше ненужного копирования данных.

3. Макросы нового поколения: macro_rules! 2.0 и процедурные макросы

Макросы — мощный инструмент метапрограммирования в Rust. В 2025 году система макросов получила значительные улучшения. Во-первых, появилась вторая версия декларативных макросов macro_rules!, а во-вторых, процедурные макросы стали проще в отладке.

Основные улучшения в macro_rules! 2.0:

  • Поддержка вложенных повторов: Теперь можно легко обрабатывать сложные структуры данных.
  • Улучшенная гигиена: Меньше шансов случайно "захватить" переменные из внешней области видимости.
  • Лучшие сообщения об ошибках: Компилятор теперь точнее указывает, где именно в макросе произошла ошибка.

Пример: Создание простого builder-паттерна с помощью макроса

// Макрос 2.0 для генерации структуры и её builder'а
macro_rules! define_builder {                

Блоги

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