Envisagez-vous d’apprendre le langage Rust en tant que développeur ? Cet article met en lumière les atouts de Rust, un des langages de programmation système les plus prisés, afin de vous aider à prendre une décision éclairée.
Nous explorerons ici les spécificités de Rust, telles que son système de typage, sa gestion de la mémoire et son concept de propriété. De plus, nous vous fournirons une sélection de ressources pour faciliter votre apprentissage.
C’est parti !
Qu’est-ce que Rust précisément ?
Rust est un langage de programmation système, initialement un projet personnel de Graydon Hoare en 2006. En moins de dix ans, il s’est imposé comme une référence en programmation système et applications connexes. Un développeur Rust peut espérer un salaire annuel moyen d’environ 120 000 $.
Si vous songez à migrer de C++ vers Rust ou simplement à vous initier à un nouveau langage, Rust est un excellent choix ! L’enquête StackOverflow Developer l’a désigné langage de programmation le plus apprécié, et ce, pendant sept années consécutives.
Source de l’image : StackOverflow
Rust combine la performance des langages système bas niveau comme C et C++ avec la sécurité des langages haut niveau tels que Python.
Il est utilisé dans des projets notables comme Dropbox, Firefox, WebAssembly et la programmation embarquée, témoignant de sa polyvalence. De plus, Rust offre une gestion intégrée des dépendances via Cargo.
Cargo : L’outil de gestion des paquets de Rust
Cargo est le gestionnaire de paquets de Rust. Il permet d’installer des bibliothèques à partir de crates.io, le dépôt officiel de paquets Rust. Cargo fait office non seulement de gestionnaire de paquets, permettant de rechercher, installer et gérer les dépendances, mais également de lanceur de tests, générateur de documentation et système de construction.
Maintenant que vous avez une vue d’ensemble de Rust, examinons en détail quelques-unes de ses caractéristiques qui en font un langage de programmation système très apprécié.
Des messages d’erreur clairs et précis
En tant que programmeur débutant, vous rencontrerez des erreurs et passerez du temps à déboguer. L’efficacité du processus dépendra de la qualité des messages d’erreur et des avertissements du compilateur, qui sont cruciaux pour une résolution rapide des problèmes.
Exemple de message d’erreur
Quand votre code ne compile pas correctement, Rust fournit des messages d’erreur très informatifs, expliquant ce qui doit être corrigé et où.
Dans l’exemple suivant, la variable `num2` est définie à l’intérieur de la fonction `inner()`. Son accès est donc limité à cette fonction. Si vous tentez d’y accéder depuis l’extérieur, le compilateur signalera une erreur :
fn main() { let num1 = 10; fn inner(){ let num2 = 9; } println!("La valeur de num2 est : {}", num2); }
Le message d’erreur qui s’ensuit est explicite quant à la nature du problème et aux solutions possibles.
error[E0425]: impossible de trouver la valeur `num2` dans cette portée --> src/main.rs:6:42 | 6 | println!("La valeur de num2 est : {}", num2); | ^^^^ aide : une variable locale avec un nom similaire existe : `num1`
Avertissements lors de la compilation
Le compilateur émet également des avertissements utiles concernant les problèmes potentiels dans votre code. Si vous définissez des variables sans jamais les utiliser par la suite, Rust vous le signalera avec un avertissement, comme illustré ci-dessous.
fn main() { let num1 = 10; let num2 = 9; println!("La valeur de num1 est : {}", num1); }
Dans ce cas, la variable `num2` est déclarée mais jamais employée.
warning: variable inutilisée : `num2` --> src/main.rs:3:9 | 3 | let num2 = 9; | ^^^^ aide : si c'est intentionnel, préfixez-la avec un underscore : `_num2` |
Un langage fortement typé
Une autre raison de choisir Rust pour vos projets est son système de type. Rust est un langage fortement typé, ce qui signifie qu’il n’autorise pas la conversion implicite de type. Ce type de conversion se produit quand un langage peut transformer automatiquement une valeur d’un type de données vers un autre.
Par exemple, le code Python suivant s’exécutera sans erreur. En Python, un nombre non nul est évalué comme True. Par conséquent, la condition `if` est satisfaite même si 10 est un entier et non un booléen.
num1 = 10 if num1: num2 = 9 print(f"num2 est {num2}") # Sortie : num2 est 9
En revanche, Rust ne procède pas à de telles conversions implicites. Le code suivant génèrera une erreur :
fn main() { let num1 = 10; if num1{ let num2 = 9; } }
L’erreur indique une incompatibilité de type : le compilateur attendait un booléen mais a rencontré un entier.
error[E0308]: types incompatibles --> src/main.rs:3:8 | 3 | if num1{ | ^^^^ attendait un `bool`, a trouvé un entier
Sécurité mémoire
La sécurité de la mémoire est un autre avantage majeur de Rust. Voici un aperçu de son fonctionnement.
Les variables doivent être initialisées avant d’être utilisées
En Rust, toutes les variables doivent être initialisées avant de pouvoir être utilisées. Dans des langages comme C, le code ci-dessous, où la variable `num` n’est pas initialisée, compilera et s’exécutera sans erreur. La valeur de la variable non initialisée sera une valeur résiduelle.
#include <stdio.h> int main(void) { int num; printf("La valeur de num est %d", num); return 0; } // Sortie : La valeur de num est 0
Si vous essayez de faire la même chose en Rust, vous obtiendrez une erreur de compilation. Rust n’a pas de notion de garbage collector.
fn main() { let num:i32; println!("La valeur de num est : {}",num); }
error[E0381]: la liaison utilisée `num` n'est pas initialisée --> src/main.rs:3:40 | 2 | let num:i32; | --- liaison déclarée ici mais non initialisée 3 | println!("La valeur de num est : {}",num); | ^^^ `num` utilisé ici mais non initialisé |
Sécurité mémoire au moment de la compilation
Rust assure la sécurité de la mémoire au moment de la compilation. Considérons cet exemple simple : Même si la condition `if` est toujours vraie, ce qui signifie que la valeur de `num` sera toujours 100, nous obtiendrons une erreur lors de la tentative d’affichage de la valeur de `num`.
fn main() { let num:i32; if true{ num = 100; } println!("La valeur de num est : {}", num); }
Cela est dû au fait que l’évaluation de la condition se produit à l’exécution, et que le compilateur ne peut pas garantir que `num` aura une valeur au moment de la compilation.
error[E0381]: la liaison utilisée `num` est potentiellement non initialisée --> src/main.rs:6:41 | 2 | let num:i32; | --- liaison déclarée ici mais non initialisée 3 | if true{ | ---- si cette condition `if` est `false`, `num` n'est pas initialisée 4 | num = 100; 5 | } | - un bloc `else` pourrait manquer ici, initialisant `num` 6 | println!("La valeur de num est : {}", num); | ^^^ `num` utilisé ici mais potentiellement non initialisé
En regardant de plus près le message d’erreur, on voit qu’avec une instruction `else`, on peut s’assurer que `num` aura une valeur. Le code suivant s’exécutera donc sans problème, car le compilateur peut déterminer qu’une valeur sera affectée à `num` au moment de la compilation.
fn main() { let num:i32; if true{ num = 100; } else{ num = 50; } println!("La valeur de num est : {}", num); }
La valeur de num est : 100
Immuabilité des variables
Il est également important de souligner que les variables sont immuables par défaut en Rust. Cela signifie que vous n’avez pas à vous soucier d’écraser accidentellement une valeur de variable. Voici un exemple :
fn main() { let num1 = 10; num1 = 5; println!("La valeur de num1 est : {}", num1); }
Comme `num1` est initialisée à 10, lorsque vous essayez d’y affecter la valeur 5, vous obtenez un message d’erreur indiquant « impossible d’assigner deux fois à la variable immuable `num1` ».
error[E0384]: impossible d'assigner deux fois à la variable immuable `num1` --> src/main.rs:3:5 | 2 | let num1 = 10; | ---- | | | première assignation à `num1` | aide : envisagez de rendre cette liaison mutable : `mut num1` 3 | num1 = 5; | ^^^^^^^^ impossible d'assigner deux fois à la variable immuable
Propriété et emprunt
Le système de propriété de Rust est au cœur de sa sécurité mémoire. Il repose sur le principe suivant :
Chaque objet a un propriétaire unique. Quand le propriétaire sort de la portée, l’objet est libéré.
Prenons un exemple : nous initialisons une chaîne `str1` puis transférons sa valeur à `str2`. Comme un objet ne peut avoir qu’un seul propriétaire, `str1` est invalidée dès que sa valeur est déplacée vers `str2`.
fn main() { let str1 = String::from("Rust"); let str2 = str1; println!("La valeur de str1 est : {}", str1); }
error[E0382]: emprunt de la valeur déplacée : `str1` --> src/main.rs:4:42 | 2 | let str1 = String::from("Rust"); | ---- le déplacement a lieu car `str1` a le type `String`, qui n'implémente pas le trait `Copy` 3 | let str2 = str1; | ---- la valeur est déplacée ici 4 | println!("La valeur de str1 est : {}", str1); | ^^^^ valeur empruntée ici après le déplacement
Pour comprendre et apprécier pleinement le fonctionnement du système de propriété, il est essentiel d’étudier les concepts d’emprunt et de références.
Développement rapide
Jusqu’ici, nous avons exploré plusieurs atouts du langage Rust. Pour récapituler :
- Rust est optimisé pour la vitesse et la sécurité.
- Il intègre un gestionnaire de paquets et un système de construction.
- Il propose une bibliothèque standard riche.
En résumé, Rust répond aux attentes des développeurs. Il permet de développer des applications rapidement, avec un minimum de débogage et des builds efficaces.
Développement multiplateforme
Rust vous permet de développer sur la plateforme de votre choix, prenant en charge les plus courantes : Linux, macOS et Windows.
Le développement est simplifié car vous pouvez compiler le code source Rust en un exécutable sans dépendre d’outils de construction externes.
Une communauté active est un atout majeur dans l’apprentissage. Rust bénéficie d’une base d’utilisateurs importante et en constante expansion.
La popularité de Rust dans l’enquête de StackOverflow témoigne de l’existence d’une vaste communauté, avec de nombreux développeurs expérimentés prêts à partager leurs connaissances.
Outre la documentation officielle, il existe une documentation générée par les utilisateurs, des forums de discussion, ainsi que des groupes Rust sur Reddit et LinkedIn pour les échanges pertinents.
Ressources pour démarrer avec Rust
Cette section liste quelques ressources pour vous aider à démarrer avec Rust. Cette liste n’est pas exhaustive mais comprend des tutoriels, cours et livres recommandés pour votre apprentissage.
#1. Rust par l’exemple
Rust By Example vous enseigne les bases de Rust et de sa bibliothèque standard à travers une série d’exemples que vous pouvez tester dans un éditeur en ligne.
Les thèmes abordés incluent les caisses, Cargo, les génériques, les traits, la gestion des erreurs et bien d’autres.
#2. Rustlings
Rustlings est une autre ressource d’apprentissage officielle. Elle est similaire à Rust par exemple. Cependant, il vous faudra configurer votre environnement de développement, cloner un dépôt d’exemples et résoudre des exercices pour maîtriser les concepts.
#3. Exercism Rust Track
Exercism propose plus de 100 exercices pour vous aider à progresser et évaluer votre compréhension de Rust. Exercism est une plateforme gratuite où vous pouvez bénéficier du mentorat de programmeurs expérimentés.
#4. Cours intensif ultime sur Rust
Le cours Ultimate Rust Crash enseigné par Nathan Stocks sur Udemy traite les sujets suivants :
- Les fondements de la programmation Rust.
- Le système de modules de Rust.
- Les types de données et le contrôle de flux.
- Les références et l’emprunt.
- Les structures, traits et collections.
#5. Ultimate Rust 2 : Concepts intermédiaires
Ultimate Rust 2 est un cours de suivi du cours intensif précédent, abordant les sujets suivants :
- Les fermetures.
- Les itérateurs.
- La gestion des erreurs.
- Les tests unitaires et d’intégration.
- La journalisation, le multithreading et les canaux.
#6. Rust lang : Le guide complet du débutant 2023
Ce cours Udemy de Catalin Stefan propose un apprentissage complet de la programmation Rust, avec notamment :
- Les bases de Rust.
- Les types de données et les structures de contrôle.
- Les fonctions et les traits.
- La gestion de la mémoire.
- La concurrence.
#7. Programmation de Rust : développement de systèmes rapides et sûrs
Programming Rust, publié par O’Reilly, est un ouvrage de référence pour l’apprentissage de Rust, couvrant notamment :
- Les types de données fondamentaux.
- La propriété et l’emprunt.
- La programmation asynchrone.
- Le développement d’applications multithread rapides.
- Les fermetures et itérateurs.
- Les collections.
#8. Le langage de programmation Rust, 2e édition
Le langage de programmation Rust, rédigé par des contributeurs reconnus de la communauté Rust, aborde en profondeur tous les aspects de Rust, notamment :
- La propriété et l’emprunt.
- Les génériques et les traits.
- Les pointeurs intelligents et le multithreading.
- Les tests et la gestion des erreurs.
#9. Le guide de référence complet de la programmation Rust
Ce guide de Packt explore les points suivants :
- L’implémentation des structures de données en Rust.
- L’écriture de composants réutilisables et testables.
- La conception d’algorithmes d’applications multithreads.
- Les applications de Rust dans les applications WebAssembly, réseau et en ligne de commande.
#10. Projets créatifs pour les programmeurs Rust
Si vous êtes un développeur expérimenté, vous pouvez consolider vos compétences en réalisant des projets dans votre domaine d’intérêt. Creative Projects for Rust Programmers de Packt vous propose d’apprendre Rust à travers des projets tels que :
- La création de services Web REST.
- Le développement de jeux 2D.
- Le développement d’applications Web avec WebAssembly.
- La réalisation d’émulateurs de langage machine.
- Et bien plus !
Conclusion
Cet article vous a donné un aperçu de Rust en tant que langage de programmation système, en soulignant ses avantages tels que la sécurité mémoire, la gestion améliorée des dépendances. Nous vous avons également fourni une liste de ressources pour faciliter votre apprentissage de Rust.
Pour aller plus loin, nous vous encourageons à choisir une ou plusieurs des ressources mentionnées pour acquérir les bases de Rust. Bonne programmation !
Vous pouvez également explorer certains des meilleurs fournisseurs d’hébergement de serveurs Rust.