Rust en 2025 : quoi de neuf ? Possibilités pratiques
L'année 2025 a été marquante pour l'écosystème Rust. Ce langage, qui a déjà conquis le cœur des programmeurs système, des développeurs web et des créateurs d'outils en ligne de commande, a reçu une série de mises à jour très attendues. Si en 2023-2024 l'accent était mis sur la stabilisation et l'amélioration de la boîte à outils, en 2025 l'accent s'est déplacé vers la simplification radicale de l'écriture de code complexe et l'augmentation des performances sans perte de sécurité.
Dans cet article, nous allons analyser trois innovations clés déjà disponibles dans la version stable de Rust 2025, et les illustrer avec des exemples concrets. Que vous suiviez l'évolution de Rust ou que vous commenciez tout juste à le découvrir, ce contenu vous aidera à vous mettre rapidement à jour.
1. Itérateurs asynchrones : async gen et async for
L'un des sujets les plus brûlants en 2025 a été la stabilisation des générateurs et itérateurs asynchrones. Auparavant, écrire un itérateur asynchrone nécessitait une implémentation manuelle du trait Stream ou l'utilisation de crates tiers. Désormais, tout est plus simple et plus élégant.
La nouveauté clé est le mot-clé async combiné avec gen et la possibilité d'utiliser async for dans les boucles. Cela permet d'écrire du code qui génère et consomme des séquences de données de manière asynchrone, sans bloquer le fil d'exécution.
Exemple : Générateur asynchrone de nombres de Fibonacci
use std::time::Duration;use tokio::time::sleep;
// Générateur asynchrone qui "produit" des nombres de Fibonacci avec un délaiasync 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; // Simulation d'un travail asynchrone yield b; // Mot-clé yield let next = a + b; a = b; b = next; } }}
#[tokio::main]async fn main() { println!("Nombres de Fibonacci asynchrones (10 premiers) :"); // Utilisation de async for pour la consommation async for number in async_fibonacci(10) { println!("Reçu : {}", number); } println!("Terminé !");}Qu'est-ce que cela apporte en pratique ?
- Simplification du code : Plus besoin d'écrire des combinateurs complexes à partir du crate
futures. - Lisibilité : Le code ressemble à un générateur synchrone classique, mais fonctionne de manière asynchrone.
- Performances : Le compilateur optimise ces constructions, réduisant les frais généraux au minimum.
C'est particulièrement utile pour le traitement de flux de données provenant du réseau, la lecture de gros fichiers ou le travail avec des connexions WebSocket.
2. Vérificateur d'emprunt amélioré : Polonius stabilisé
Le vérificateur d'emprunt est "l'âme" de Rust, garantissant la sécurité de la mémoire sans ramasse-miettes. Cependant, les débutants (et même les développeurs expérimentés) rencontraient souvent des situations où le compilateur rejetait un code parfaitement sûr. En 2025, le modèle d'emprunt Polonius fait enfin partie du compilateur stable.
Polonius utilise une analyse de flux de données plus précise, permettant au compilateur de "comprendre" des schémas plus complexes de travail avec les références.
Exemple : Problème des "deux emprunts mutables"
Auparavant, ce code ne se compilait pas :
fn push_and_pop(vec: &mut Vec<i32>) -> &i32 { vec.push(1); // Erreur : impossible de prendre une référence mutable (push) puis immuable (pop) let last = vec.last().unwrap(); last}Avec Rust 2025 et Polonius, cela fonctionne ! Le compilateur voit qu'après push, la référence mutable n'est plus utilisée, et autorise la prise d'une référence immuable sur le dernier élément. Voici comment