Retour aux cours
AI034 Professional

Le langage de programmation Rust

Un guide complet et introductif à Rust, couvrant les concepts de programmation système, la sécurité mémoire, la concurrence et l'outil Rust (Cargo, rustup). Il passe du syntaxe de base à la création de projets complets comme un serveur web multithreadé.

5.0
63.0h
763 étudiants
0 j'aime
Intelligence Artificielle
Commencer à apprendre

Aperçu du cours

📚 Résumé du contenu

Un guide complet d'introduction à Rust, couvrant les concepts de programmation système, la sécurité mémoire, la concurrence et l'éco-système Rust (Cargo, rustup). Il passe du syntaxe de base à la construction de projets complets comme un serveur web multithreadé.

Maîtrisez l'art de la programmation système sûre, rapide et concurrente avec le guide définitif de Rust.

Auteur : Steve Klabnik et Carol Nichols, avec des contributions de la communauté Rust

Remerciements : Contributions de la communauté Rust ; publié en version imprimée et eBook par No Starch Press.

🎯 Objectifs d'apprentissage

  1. Installer et gérer efficacement les outils Rust via rustup sur différentes plateformes.
  2. Écrire, compiler et exécuter un programme Rust basique, en identifiant les composants anatomiques fondamentaux du code.
  3. Utiliser Cargo pour créer des structures de projet standardisées, gérer les compilations et produire des binaires optimisés pour la version de production.
  4. Capturer et stocker l'entrée utilisateur tout en gérant la mutabilité des variables et les éventuelles erreurs liées aux entrées/sorties.
  5. Intégrer des dépendances externes via Cargo et gérer des compilations reproductibles grâce au fichier Cargo.lock.
  6. Implémenter la logique de jeu en utilisant l'inference de type, la parse de chaînes, les boucles et l'opérateur de flux de contrôle match.
  7. Différencier les constantes et l'ombre de variables pour gérer l'immutabilité des données et la portée.
  8. Implémenter correctement les types scalaires (entiers, flottants, booléens, caractères) et les types composés (tuple, tableau).
  9. Distinction entre instructions et expressions afin de définir des fonctions avec des valeurs de retour spécifiques.
  10. Différencier la mémoire pile et la mémoire tas, et expliquer comment Rust gère les données sur le tas.

🔹 Leçon 1 : Démarrage avec Rust

Aperçu : Cette leçon offre une introduction complète à l'éco-système Rust, en se concentrant sur la configuration de l'environnement et le workflow fondamental d'un développeur Rust. Les étudiants passeront de l'installation du langage via rustup à l'écriture d'un programme "Bonjour, monde !" manuel, puis maîtriseront Cargo, le système de build officiel de Rust et son gestionnaire de paquets, pour une gestion professionnelle des projets et une optimisation des versions de publication.

Objectifs d'apprentissage :

  • Installer et gérer efficacement les outils Rust via rustup sur différentes plateformes.
  • Écrire, compiler et exécuter un programme Rust basique, en identifiant les composants anatomiques fondamentaux du code.
  • Utiliser Cargo pour créer des structures de projet standardisées, gérer les compilations et produire des binaires optimisés pour la version de production.

🔹 Leçon 2 : En pratique : Programmation d'un jeu de devinette

Aperçu : Cette leçon guide les développeurs dans la construction d'un jeu de devinette fonctionnel basé sur ligne de commande en Rust. Elle couvre des concepts fondamentaux de programmation système tels que le traitement des entrées utilisateur, l'intégration de crates externes pour la génération de nombres aléatoires, et l'approche unique de Rust en matière de sécurité mémoire et de gestion des erreurs via le type Result et le pattern matching. À la fin, les apprenants disposeront d'une application robuste capable de gérer les entrées invalides et garantissant des compilations reproductibles.

Objectifs d'apprentissage :

  • Capturer et stocker l'entrée utilisateur tout en gérant la mutabilité des variables et les éventuelles erreurs liées aux entrées/sorties.
  • Intégrer des dépendances externes via Cargo et gérer des compilations reproductibles grâce au fichier Cargo.lock.
  • Implémenter la logique du jeu en utilisant l'inference de type, la parse de chaînes, les boucles et l'opérateur de flux de contrôle match.

🔹 Leçon 3 : Concepts de programmation courants

Aperçu : Cette leçon couvre les blocs de base fondamentaux de la programmation en Rust, en se concentrant sur le stockage et la manipulation des données. Elle explore les nuances de l'ombre de variables et des constantes, la catégorisation des données en types scalaires et composés, les règles structurelles des fonctions, ainsi que la logique régissant le flux de contrôle et l'exécution répétitive.

Objectifs d'apprentissage :

  • Différencier les constantes et l'ombre de variables pour gérer l'immutabilité des données et la portée.
  • Implémenter correctement les types scalaires (entiers, flottants, booléens, caractères) et les types composés (tuple, tableau).
  • Distinction entre instructions et expressions afin de définir des fonctions avec des valeurs de retour spécifiques.

🔹 Leçon 4 : Compréhension de la propriété et de la mémoire

Aperçu : Cette leçon explore l'approche unique de Rust en matière de gestion de mémoire via son système de propriété. Au lieu de s'appuyer sur un ramasse-miettes ou une gestion manuelle de la mémoire, Rust utilise un ensemble de règles vérifiées au moment de la compilation pour garantir la sécurité mémoire. Ce chapitre couvre les mécanismes de la pile et du tas, le cycle de vie des données, et comment les références et les tranches permettent un accès sécurisé et efficace à la mémoire sans transfert de propriété.

Objectifs d'apprentissage :

  • Distinction entre la mémoire pile et la mémoire tas, et explication de la manière dont Rust gère les données sur le tas.
  • Appliquer les trois règles de la propriété pour prédire la validité et la portée des variables.
  • Démontrer la différence entre les opérations Move, Clone et Copy.

🔹 Leçon 5 : Structures : Gestion des données liées

Aperçu : Cette leçon explore comment regrouper des données liées dans des types personnalisés à l'aide de structures (struct) afin de créer un code plus significatif et organisé. Elle couvre la définition et l'instanciation de diverses formes de structures (classiques, tuple, unit-like), la gestion de la propriété des données au sein de ces structures, et l'amélioration des structures grâce à des traits dérivés comme Debug et des méthodes personnalisées définies via des blocs impl.

Objectifs d'apprentissage :

  • Définir et instancier des structures en utilisant des champs nommés, une syntaxe raccourcie et une syntaxe de mise à jour.
  • Différencier les structures classiques, les structures tuple et les structures unit-like, et identifier leurs cas d'utilisation.
  • Implémenter le trait Debug et utiliser le macro dbg! pour inspecter les données de structure.

🔹 Leçon 6 : Énumérations et correspondance de motifs

Aperçu : Cette leçon explore comment Rust utilise les énumérations (enums) pour définir des types en énumérant leurs variantes possibles, offrant une méthode plus flexible pour grouper des constantes et des données connexes que les structures seules. Elle couvre le rôle crucial de l'énumération Option pour éliminer les erreurs de pointeur nul, et démontre comment les constructions match et if let fournissent un puissant flux de contrôle exhaustif pour manipuler des motifs de données complexes de manière sécurisée.

Objectifs d'apprentissage :

  • Définir des énumérations avec différents types de données et implémenter des méthodes dessus en utilisant des blocs impl.
  • Expliquer les avantages de sécurité de l'énumération Option<T> par rapport aux valeurs nulles traditionnelles.
  • Créer des expressions match exhaustives qui lient les valeurs internes des variantes et utilisent des espaces réservés généraux.

🔹 Leçon 7 : Modules, Paquetages et Crates

Aperçu : Cette leçon explore comment Rust organise le code pour améliorer sa lisibilité et sa réutilisabilité grâce à son système de modules. Elle couvre la création d'une arborescence de modules, l'application des règles de visibilité pour contrôler la visibilité des éléments, et l'utilisation des chemins et des mots-clés comme use et pub pour gérer la portée et créer des API propres.

Objectifs d'apprentissage :

  • Organiser le code dans une structure hiérarchique en utilisant des modules et l'arborescence de modules.
  • Référencer des éléments de code à l'aide de chemins absolus ou relatifs.
  • Contrôler la visibilité des fonctions, modules et champs en utilisant le mot-clé pub et les règles de visibilité.

🔹 Leçon 8 : Collections courantes

Aperçu : Cette leçon explore les collections de la bibliothèque standard de Rust, en se concentrant spécifiquement sur les Vecteurs, les Chaînes et les Tables hachées. Ces structures de données sont stockées sur le tas, ce qui leur permet de croître ou de décroître dynamiquement à runtime, et la leçon détaille comment les règles de propriété et d'emprunt de Rust garantissent la sécurité mémoire et les performances lors de la gestion de ces listes de valeurs, de texte UTF-8 et d'associations clé-valeur.

Objectifs d'apprentissage :

  • Implémenter des listes dynamiques à l'aide de Vec<T> et gérer leur cycle de vie grâce au vérificateur d'emprunts.
  • Manipuler le texte encodé en UTF-8 à l'aide du type String, tout en naviguant dans les complexités de sa représentation interne et de la concaténation.
  • Appliquer HashMap<K, V> pour stocker et mettre à jour efficacement des données associées en utilisant l'API Entry et des considérations personnalisées en matière de hachage.

🔹 Leçon 9 : Stratégies de gestion des erreurs

Aperçu : Cette leçon explore la philosophie robuste de la gestion des erreurs de Rust, qui distingue entre erreurs récupérables et irrécupérables. Les étudiants apprendront à utiliser la macro panic! pour les erreurs fatales, l'énumération Result pour les échecs gérables, et l'opérateur ? pour simplifier la propagation des erreurs. En outre, la leçon couvre la manière dont le système de types de Rust peut forcer la validation des données et maintenir l'intégrité du programme.

Objectifs d'apprentissage :

  • Identifier quand utiliser panic! irrécupérable plutôt que Result récupérable selon les critères d'état défectueux.
  • Utiliser les traces d'arrière-plan pour déboguer l'origine des erreurs irrécupérables.
  • Implémenter la propagation des erreurs en utilisant l'opérateur ? et modifier la fonction main pour supporter les retours d'erreurs.

🔹 Leçon 10 : Généricité, Traits et Durées de vie

Aperçu : Cette leçon explore les outils de Rust pour une abstraction efficace : les génériques pour réduire la duplication de code entre types, les traits pour définir un comportement partagé (interfaces), et les durées de vie pour assurer la sécurité mémoire sans gestion manuelle. Ensemble, ces fonctionnalités permettent aux développeurs d'écrire du code hautement performant et réutilisable, validé par le compilateur pour éviter les références pendantes et les incohérences de type.

Objectifs d'apprentissage :

  • Définir et utiliser des paramètres de type générique dans les fonctions, structures et énumérations pour gérer plusieurs types de données.
  • Implémenter un comportement partagé à l'aide de traits et des bornes de traits pour restreindre les types génériques.
  • Appliquer les annotations de durée de vie et les règles d'élimination pour gérer la validité des références et satisfaire le vérificateur d'emprunts.

🔹 Leçon 11 : Écriture de tests automatisés

Aperçu : Cette leçon explore la mise en œuvre et l'organisation des tests automatisés en Rust. Elle couvre les exigences structurelles d'une fonction de test, l'utilisation des macros d'assertion pour vérifier la logique, et les distinctions techniques entre tests unitaires et tests d'intégration. Les apprenants comprendront également comment contrôler le comportement du runner de tests Rust pour gérer le flux d'exécution et la visibilité.

Objectifs d'apprentissage :

  • Définir la structure et les métadonnées requises pour une fonction de test Rust valide.
  • Mettre en œuvre des vérifications d'égalité et de panique pour garantir la fiabilité du code.
  • Configurer le runner de tests pour une exécution parallèle ou séquentielle, et la visibilité de la sortie du programme.

🔹 Leçon 12 : Projet I/O : Outil en ligne de commande

Aperçu : Cette leçon guide les développeurs dans la création d'un outil en ligne de commande fonctionnel (une version simplifiée de grep) en Rust. Elle met l'accent sur la transition d'un script simple en un binaire modulaire et prêt à production, en soulignant la parse d'arguments sécurisée en mémoire, l'entrée/sortie de fichiers, et la séparation des préoccupations entre la logique de bibliothèque et l'interface en ligne de commande. Les apprenants implémenteront une gestion robuste des erreurs et développeront des fonctionnalités en utilisant le développement piloté par les tests (TDD), tout en gérant l'état de l'application via des variables d'environnement.

Objectifs d'apprentissage :

  • Capturer et transformer les arguments en ligne de commande en objets de configuration structurés.
  • Refactoriser le code pour respecter le principe de séparation des préoccupations dans les projets binaires.
  • Implémenter la logique centrale en suivant un cycle TDD avec des annotations de durée de vie.

🔹 Leçon 13 : Fonctionnalités fonctionnelles : Itérateurs et Fermetures

Aperçu : Cette leçon explore les fonctionnalités de programmation fonctionnelle de Rust, en se concentrant spécifiquement sur les fermetures (closures) et les itérateurs. Les fermetures sont des fonctions anonymes pouvant capturer leur environnement, régies par les traits Fn, tandis que les itérateurs offrent une manière paresseuse et efficace de traiter des séquences d'éléments. Ensemble, ces fonctionnalités permettent un code expressif respectant le principe d'abstraction « zéro coût » de Rust, souvent égale ou supérieure en performance aux boucles traditionnelles.

Objectifs d'apprentissage :

  • Définir des fonctions anonymes (fermetures) et expliquer comment elles capturent les variables de leur environnement par emprunt ou mouvement.
  • Différencier les trois traits Fn (Fn, FnMut et FnOnce) et comprendre comment le compilateur infère les types de fermeture.
  • Implémenter le trait Iterator en utilisant la méthode next et distinguer les adaptateurs consommateurs des adaptateurs d'itérateurs.

🔹 Leçon 14 : Cargo avancé et Crates.io

Aperçu : Cette leçon explore les fonctionnalités avancées du gestionnaire de paquets de Rust, Cargo, et de son éco-système, Crates.io. Elle se concentre sur l'optimisation des compilations via les profils de publication, la création de documentation professionnelle intégrant des tests, et la maîtrise de l'architecture des API publiques. En outre, elle couvre le cycle de vie d'un crate — de la publication et de la versionning jusqu'à la gestion de projets multi-paquetages via les workspaces et l'extension des fonctionnalités natives de Cargo.

Objectifs d'apprentissage :

  • Configurer les profils de publication pour équilibrer la vitesse de compilation et les performances à l'exécution.
  • Générer et valider des commentaires de documentation qui servent à la fois de guides utilisateurs et de tests automatisés.
  • Concevoir une API publique pratique en utilisant les réexportations (pub use) pour découpler la structure interne de l'utilisation externe.

🔹 Leçon 15 : Pointeurs intelligents

Aperçu : Cette leçon explore les pointeurs intelligents de Rust — des structures de données agissant comme des pointeurs mais portant des métadonnées et des fonctionnalités supplémentaires. Nous nous concentrons sur la gestion de l'allocation sur le tas avec Box<T>, l'activation de la possession partagée avec Rc<T>, et le contournement des règles strictes d'emprunt via le motif d'immutabilité intérieure avec RefCell<T>. Nous couvrons également les traits Deref et Drop qui sous-tendent le comportement des pointeurs intelligents et le nettoyage des ressources.

Objectifs d'apprentissage :

  • Implémenter des structures de données récursives en utilisant Box<T> pour fournir une indirection et une taille mémoire connue.
  • Personnaliser le comportement du pointeur et la gestion des ressources en utilisant les traits Deref et Drop.
  • Gérer plusieurs propriétaires et la mutabilité vérifiée à runtime en combinant Rc<T> et RefCell<T>.

🔹 Leçon 16 : Concurrence sans crainte

Aperçu : Cette leçon explore la philosophie de la « concurrence sans crainte » de Rust, démontrant comment le langage exploite ses systèmes de propriété et de type pour transformer la programmation concurrente d'un piège de runtime en une certitude au moment de la compilation. Nous couvrons la création de threads, la communication sécurisée via le passage de messages, la gestion de l'état partagé avec les verrous (mutexes), et les traits fondamentaux définissant la sécurité des threads.

Objectifs d'apprentissage :

  • Créer et gérer des threads en utilisant spawn et join, tout en résolvant les conflits de propriété avec le mot-clé move.
  • Implémenter la concurrence par passage de messages en utilisant des canaux mpsc pour transférer des données de manière sécurisée entre threads.
  • Gérer l'état partagé entre plusieurs threads en utilisant Mutex<T> pour l'exclusion mutuelle et Arc<T> pour le comptage de référence sécurisé par les threads.

🔹 Leçon 17 : Programmation orientée objet en Rust

Aperçu : Cette leçon explore comment Rust implémente les principes fondamentaux de la programmation orientée objet (POO), en se concentrant particulièrement sur l'encapsulation et la polymorphisme. Elle détaille les mécanismes des objets de trait pour gérer des collections hétérogènes et les compromis entre l'envoi statique et dynamique. Enfin, elle compare l'implémentation du modèle d'état classique à une approche plus idiomatique de Rust consistant à encoder les états et les comportements directement dans le système de types.

Objectifs d'apprentissage :

  • Implémenter l'encapsulation en Rust en utilisant des modules et des modificateurs de visibilité pour cacher l'état interne.
  • Utiliser les objets de trait pour obtenir la polymorphisme et comprendre les implications de performance entre l'envoi statique et dynamique.
  • Appliquer le modèle d'état pour gérer les comportements complexes des objets et les transitions entre états.

🔹 Leçon 18 : Modèles et correspondance avancés

Aperçu : Cette leçon explore la profondeur du système de correspondance de motifs de Rust, allant au-delà des simples bras match vers une extraction sophistiquée de données et un flux de contrôle. Les étudiants maîtriseront la distinction entre motifs irrefutables et refutables, apprendront à déconstruire des structures complexes imbriquées, et utiliseront une syntaxe avancée comme les gardes match et les liaisons pour écrire un code plus expressif et sûr.

Objectifs d'apprentissage :

  • Différencier les motifs irrefutables et refutables et les appliquer aux bons constructeurs Rust (par exemple, let vs. if let).
  • Déconstruire des structures, énumérations et tuples pour extraire des données spécifiques dans des variables locales.
  • Employer une syntaxe de motif avancée, incluant des plages, plusieurs motifs, l'ignorance de valeurs, et les liaisons @ pour des correspondances conditionnelles complexes.

🔹 Leçon 19 : Fonctionnalités avancées et Rust non sécurisé

Aperçu : Cette leçon explore les « superpouvoirs » de Rust qui permettent aux développeurs de contourner certaines restrictions du compilateur et de créer des abstractions très flexibles. Nous couvrons l'utilisation de Rust non sécurisé pour la manipulation de mémoire de bas niveau, des techniques avancées de traits pour des relations de type complexes, et les puissantes capacités de métaprogrammation des macros déclaratives et procédurales.

Objectifs d'apprentissage :

  • Différencier Rust sécurisé et les « superpouvoirs » non sécurisés nécessaires pour manipuler des pointeurs bruts et appeler des fonctions non sécurisées.
  • Implémenter des modèles de traits avancés incluant les types associés, le surcharge d'opérateurs, les supertraits et le modèle Newtype.
  • Distinguer les appels de méthode en utilisant la syntaxe entièrement qualifiée et gérer des types complexes comme les types de taille dynamique (DST) et les alias de type.

🔹 Leçon 20 : Projet final : Serveur web multithreadé

Aperçu : Cette leçon guide le développement d'un serveur web haute performance en utilisant les primitives réseau et concurrentes de Rust. Elle couvre la transition d'un écouteur TCP basique à un système sophistiqué multithreadé utilisant un pool de threads personnalisé. Les étudiants apprendront à gérer des flux de bas niveau, à implémenter un passage de messages basé sur des travailleurs pour distribuer les tâches, et à assurer la stabilité du système grâce à un mécanisme de fermeture gracieuse.

Objectifs d'apprentissage :

  • Établir et gérer des connexions TCP : lier un serveur à un port local et gérer les flux d'octets entrants.
  • Parser et répondre aux requêtes HTTP : lire les données de requête brutes et construire des réponses HTTP valides avec des lignes d'état et des corps HTML.
  • Concevoir un pool de threads personnalisé : utiliser des canaux mpsc et des primitives de synchronisation (Arc, Mutex) pour distribuer les tâches sur un nombre fini de threads.

🔹 Leçon 21 : Annexes Rust : Outils et références

Aperçu : Cette leçon fournit une référence technique complète pour le langage Rust, en se concentrant sur sa syntaxe dense, ses outils de développement automatisés et son processus d'évolution des versions. Les étudiants apprendront à naviguer dans la syntaxe chargée de symboles de Rust, à implémenter des comportements standards via des traits dérivables, et à tirer parti de l'éco-système des outils pour maintenir une haute qualité du code et suivre la philosophie du langage « stabilité sans stagnation ».

Objectifs d'apprentissage :

  • Identifier et interpréter la syntaxe : décoder les opérateurs, les symboles liés aux chemins et les contraintes génériques à l'aide de tableaux de référence standardisés.
  • Implémenter des comportements standards : automatiser l'implémentation des traits Debug, Clone, Eq, Ord et Hash en utilisant l'attribut derive.
  • Optimiser le flux de développement : utiliser rustfmt, rustfix et Clippy pour formater, réparer et analyser le code conformément aux normes communautaires.