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 {