Premiers pas avec le langage Rust

Le langage Rust est de plus en plus populaire. Celui-ci, a été élu pour la cinquième année consécutive, le langage de programmation le plus apprécié par les développeurs selon le sondage annuel de Stack Overflow. De nombreuses sociétés telles que Microsoft ou Amazon s’y intéressent également pour le développement de leurs solutions. Qu’est-ce qui rend Rust si populaire ? Pourquoi s’y intéresser ? C’est ce que nous allons découvrir dans cet article.

Il était une fois…

Rust est né en 2006, d’un projet personnel de Graydon Hoare alors employé chez Mozilla. Voyant le potentiel du langage, Mozilla décide de soutenir le développement de Rust en 2009 et présente celui-ci pour la première fois en 2010 lors du Mozilla summit. La première version stable de Rust voit le jour en 2015.

Autant dire que comparé aux autres langages comme JavaScript né en 1995, Python en 1991 ou même encore le langage C qui lui est né en 1973, Rust est très jeune.

Malgré sa jeunesse, Rust possède de nombreux atouts qui font que celui-ci est, aujourd’hui, de plus en plus utilisé, et ce dans de nombreux domaines tels que :

  • La programmation système ;
  • Les systèmes embarqués ;
  • Le cloud ;
  • Le développement web ;
  • Les outils de lignes de commandes ;
  • etc.

Il y a un véritable engouement autour de Rust, qui fait que de plus en plus d’entreprises s’y intéressent et n’hésitent pas à migrer leurs solutions vers celui-ci. Parmi celles-ci, nous pouvons citer Dropbox, Microsoft, Npm, Facebook ou encore Amazon

Certains voient même en Rust le successeur du C et du C++.

Qu’est-ce que Rust ?

Rust est un langage de programmation compilé, multiplateforme, multiparadigme, bas niveau, au typage fort et statique qui se concentre sur la sécurité et les performances. 

Oui je sais, ça en fait des concepts. Allez n’ayez pas peur je vais vous expliquer tout ça.

Un langage compilé

Contrairement à JavaScript ou Python, Rust est un langage compilé. Cela signifie que le code source est transformé, par un programme appelé compilateur, en code machine directement exécutable par votre ordinateur. L’avantage est qu’il n’est plus nécessaire de faire appel à un programme annexe pour votre programme, comme ça peut être le cas avec un langage interprété. L’autre avantage qui découle du premier est qu’un programme compilé est généralement plus rapide à l’exécution, car il n’y a pas d’étape d’interprétation.

Si vous souhaitez en savoir plus sur la compilation et l’interprétation d’un programme, je vous recommande cet article.

Multiplateforme

Rust permet de développer des programmes pouvant être exécutés sur plusieurs plateformes que ce soit Windows, Linux ou MacOS. Rust est même utilisé pour le développement de systèmes embarqués et permet donc de développer des programmes destinés à être exécutés sur des microcontrôleurs.

Du fait que Rust est un langage compilé, il est toutefois nécessaire de compiler le code source pour ces différentes plateformes.

Multiparadigme

Multiparadigme signifie qu’il est possible avec Rust de développer des programmes en utilisant différents concepts de programmation tels que la programmation fonctionnelle ou la programmation orientée objet.

Bas niveau

Rust est souvent considéré comme un langage bas niveau, car celui-ci permet de développer des programmes faisant partie du système d’exploitation, donc souvent proche du matériel comme le permet le langage C par exemple. Mais Rust, offre certaines abstractions provenant de langage de plus haut niveau notamment une gestion de la mémoire efficace ou une gestion des erreurs intelligentes.

Typage fort et statique

Un langage fortement typé (ou à typage fort) signifie que le type d’une variable est garanti et que celui-ci ne pourra pas changer en cours d’exécution comme c’est le cas en JavaScript par exemple. De ce fait, les conversions implicites de type ne sont pas permises. Statique signifie quant à lui que ces vérifications de types sont réalisées à la compilation et non à l’exécution contrairement à un langage au typage dynamique.

Un langage performant et sécurisé

Quand on parle de Rust, il y a deux adjectifs qui reviennent souvent sur la table : performant et sécurisé.

Performant

Rust est rapide, très rapide, ces performances sont souvent comparées au C/C++. Certains évoquent même la possibilité d’utiliser Rust à la place du C++ dans le développement de jeux vidéos, un domaine très exigeant niveau performance.

Sécurisé

La gestion de la mémoire a toujours été une problématique. En C/C++, c’est aux développeurs de gérer celle-ci, ce qui implique souvent des erreurs de programmation dues à de la mémoire non libérée ou encore des dépassements de mémoire tampon (buffer overflow) pouvant entraîner des bugs et même des failles de sécurité. D’autres langages comme Java ou Python par exemple, résolvent la plupart des problèmes de mémoire avec notamment l’utilisation d’un ramasse-miette (garbage collector), mais au détriment de la performance.

Rust lui propose une gestion de la mémoire sécurisée, sans utilisation de ramasse-miette et donc sans perte de performance. Le compilateur vous indiquera toutes les erreurs à la compilation et non à l’exécution. Je vous préviens, vous allez détester le compilateur de Rust, mais il va vous éviter bon nombre d’erreurs.

Ces deux atouts font de Rust un langage de choix dans la programmation système. Rust est même évoqué comme une alternative du C pour le développement du noyau Linux. Même Microsoft réfléchit sérieusement à l’utilisation de Rust dans le développement de composants Windows.

Nous reviendrons plus en détail sur la gestion de la mémoire dans le prochain article consacré à Rust.

Découvrons Rust

C’est bien beau tout ça mais il est temps de découvrir les bases de Rust.

Installation

La première étape consiste à installer Rust. Pour cela nous devons le télécharger via l’outil rustup qui est un outil permettant de gérer les versions de Rust ainsi que ses outils.

Si vous êtes sous Linux ou Mac OS, ouvrez votre terminal et écrivez la commande suivante :

Cette commande va télécharger un script qui va installer l’outil rustup qui lui va procéder à l’installation de Rust. Si tout se déroule bien vous devriez voir le message suivant :

Si vous êtes sous Windows, il suffit de se rendre sur le site officiel et de suivre les instructions.

Pour vous assurer que l’installation s’est bien déroulée, vous pouvez lancer la commande suivante dans votre terminal :

Vous devriez voir message suivant :

Celui-ci indique le numéro de version, le hash de commit de la version ainsi que la date de publication de celle-ci.

Mise à jour et désinstallation

Comme je l’ai dit, rustup permet de gérer les versions de Rust, si vous souhaitez mettre à jour celui-ci, il suffit de lancer la commande suivant dans votre terminal :

Il en est de même pour la désinstallation, il suffit de lancer la commande suivant dans votre terminal :

Et le code dans tout ça ?

Passons aux choses sérieuses et voyons à quoi ressemble du code écrit en Rust.

Le traditionnel hello world

Commençons par le traditionnel hello world. Ouvrez donc votre éditeur préféré, créez un fichier main.rs et écrivez le code suivant :

Observons la structure de ce code qui n’est pas bien compliqué à comprendre. Pour déclarer une fonction, nous utilisons le mot-clé fn suivi du nom de la fonction. Nous avons donc ici une fonction appelée main qui est une fonction un peu particulière puisque chaque programme Rust possède une fonction main qui est le point d’entrée du programme. Pour celles et ceux venant du langage C/C++ vous ne devriez pas être perdu.

La fonction main contient l’instruction suivante println!("Hello, world!"); qui permet simplement d’afficher le message Hello, world! sur la sortie standard.

Note : Vous pouvez remarquer un ! à la fin de la fonction println qui indique que celle-ci n’est pas une fonction, mais une macro. Nous n’allons pas rentrer dans les détails de ce qu’est une macro nous le verrons peut-être dans un futur article.

Le corps d’une fonction est placé entre des accolades {} et chaque instruction se termine par un point-virgule ;

Compilons maintenant notre code. Pour cela, écrivez la commande suivante dans votre terminal :

Il ne se passe rien ? Mais si voyons, nous avons vu que Rust était un langage compilé et que l’étape de compilation permet de créer un binaire exécutable. Si vous regardez dans votre dossier, vous devriez voir un fichier main (ou main.exe sur Windows). Pour exécuter le binaire, écrivez simplement la commande suivante si vous êtes sur Linux ou MacOS :

Si vous êtes sous Windows, la commande est similaire, mais il faut ajouter l’extension .exe:

Vous devriez voir s’afficher le message Hello, world!

Bravo, vous venez d’écrire votre premier programme avec Rust.

Petit tour des bases

Pour continuer, faisons un petit tour des bases de Rust.

Les variables

Les variables en Rust sont par défaut immuables (immutables en anglais) c’est-à-dire qu’il n’est pas possible de changer leur valeur après leurs déclarations. Pour déclarer une variable en Rust il suffit d’utiliser le mot-clé let :

Essayons de changer la valeur de notre variable value :

Tentons maintenant de compiler :

On obtient ce joli message d’erreur :

Le compilateur de Rust est vraiment génial, les erreurs sont explicites. Celui-ci nous indique qu’il n’est pas possible d’assigner une seconde fois une valeur à une variable immuable. Il nous explique même comment régler notre souci. Nous devons utiliser le mot-clé mut avant le nom de la variable lors de sa déclaration pour rendre celle-ci mutable :

Il existe également le mot-clé const pour déclarer une constante. La première différence avec le mot-clé let est que la valeur d’une constante doit être connue à la compilation, il n’est donc pas possible d’avoir une valeur provenant d’un appel de fonction. La seconde différence est que le type d’une constante doit également être déclaré explicitement :

Les types primitifs

Rust pratique ce qu’on appelle l’inférence de type qui permet au compilateur de déduire automatiquement les types associés aux expressions, telle qu’une déclaration de variable par exemple, sans qu’ils soient indiqués explicitement dans le code. Il est tout de même possible d’indiquer le type d’une variable. Reprenons notre exemple précédent et indiquons le type de la variable value :

La variable value est de type i32 ce qui correspond à un entier représenter sur 4 octets (32 bits).

Voyons plus en détail les types primitifs de Rust.

bool

Le type pour les valeurs booléennes est bool. Ce type peut prendre les valeurs true ou false :

char

Le type char correspond à un seul caractère :

Faites attention à bien utiliser le caractère simple quote ' et non pas le caractère double quote " qui lui représente une chaîne de caractères. Contrairement à d’autres langages (comme le C par exemple) le type char de Rust est représenté sur 4 octets pour le support d’Unicode.

Les entiers signés

Les entiers signés contiennent des valeurs entières qui peuvent être positives ou négatives. Nous distinguons cinq types d’entiers signés :

TypeValeur minValeur max
i8-128127
i16-3276832767
i32-21474836482147483647
i64-92233720368547758089223372036854775807
i128-170141183460469231731687303715884105728170141183460469231731687303715884105727

Les entiers non signés

Les entiers non signés contiennent uniquement des valeurs entières positives. Nous distinguons cinq types d’entiers non signés :

TypeValeur minValeur max
u80255
u16065535
u3204294967295
u64018446744073709551615
u1280340282366920938463463374607431768211455

Les nombres décimaux

Il existe deux types pour les nombres décimaux f32 et f64 qui correspondent respectivement à un nombre décimal représenté sur 4 octets (32 bits) et 8 octets (64 bits).

Les tableaux

Les tableaux en Rust ont une taille fixe et ne peuvent contenir que des valeurs de même type.

Note : Il est possible d’avoir des “tableaux” dynamiques en Rust, il faut pour cela utiliser la structure Vec. Il existe également d’autres types de collections disponibles dans la librairie standard de Rust comme les listes chaînées ou encore les tables de hachages.

Les tuples

Un tuple est une liste ordonnée d’éléments pouvant être de types différents. Les développeurs Python connaissent déjà bien ce type de données.

slice

Sans rentrer dans les détails et pour faire simple, le type slice est une référence (d’où la présence du caractère & qui n’est pas nouveau pour les développeurs C++) sur une partie d’une structure de données comme les tableaux par exemple :

Note :  L’opérateur .. permets de définir un intervalle d’exclusion. Par exemple 0..3 représente les éléments de 0 à 3 (exclus). Au contraire, l’opérateur ..= définit quant à lui un intervalle d’inclusion. 0..=3 représente donc les éléments de 0 à 3 (inclus).

Les chaînes de caractères

Pour déclarer une chaîne de caractères il suffit d’utiliser les doubles quote " :

Les chaînes de caractères (str) en Rust sont bien plus complexes qu’elles ont en l’air. Pour cet article nous n’allons donc pas rentrer dans les détails.

Les opérateurs

Nous n’allons pas nous attarder sur les différents opérateurs. Vous pouvez retrouver ceux-ci dans le tableau ci-dessous.

Les opérateurs arithmétiques + - * / %
Les opérateurs de comparaison == != < > <= >=
Les opérateurs logiques ! && ||
Les opérateurs d'affectations = += -= *= /= %= &= |= ^= <<= >>=
Les opérateurs bit-à-bit & | ^ << >>

Les structures de contrôle

Nous allons maintenant nous intéresser aux structures de contrôle.

if – else if – else

Comme pour la plupart des langages on retrouve le traditionnel trio: if, else if et else.

Il n’existe pas de condition ternaire comme dans la plupart des langages, mais il est possible de combiner let et if/else comme ceci :

match

Il n’existe pas d’instruction switch en Rust, et c’est pas plus mal, car je la trouve personnellement trop verbeuse et souvent source d’erreur avec l’oubli d’un break par exemple. À la place, Rust utilise ce qu’on appelle le pattern matching via l’instruction match qui est bien plus puissante qu’un simple switch.

Voici un premier exemple avec l’instruction match qui se comporte comme un switch classique :

Tout comme l’instruction if, il est également possible de procéder à une affection :

Mais l’instruction match ne s’arrête pas là, elle propose des comparaisons beaucoup plus poussées :

Tout ceci n’est qu’un avant-goût de ce qu’il est possible de réaliser avec l’instruction match.

while

L’instruction while permet de créer une boucle qui continue tant que sa condition est respectée comme pour les autres langages :

loop

L’instruction loop permet de créer une boucle infinie (oui il existe certains cas où une boucle infinie est utile).

C’est plus simple que de l’écrire avec l’instruction while :

Pour arrêter une boucle loop il suffit de faire appel à l’instruction break :

for

L’instruction for de Rust se rapproche de l’instruction for de Python. Elle permet de parcourir une à une les valeurs d’une expression renvoyant un itérateur (pour faire simple) :

Les fonctions

Nous avons déjà vu avec notre premier exemple que chaque programme Rust doit avoir une fonction principale nommée main qui est le point d’entrée du programme. Mais il est bien entendu possible de définir d’autres fonctions :

Il est également possible de définir des fonctions anonymes que l’on appelle des closures (à ne pas confondre avec les closures de JavaScript, ici cela ressemble plus aux arrow functions) :

Et la POO dans tout ça ?

Nous allons maintenant voir comment il est possible de faire de la programmation orientée objet avec Rust.

Les structures

Les structures sont ce qui se rapproche le plus des classes des autres langages de programmation. Pour créer une structure, il faut utiliser le mot-clé struct :

L’instanciation se fera ensuite de la manière suivante :

Pour accéder aux attributs de notre objet, il suffit de spécifier leur nom, comme il est coutume de faire en JavaScript :

Il est également possible de définir des méthodes sur nos structures à l’aide du mot-clé impl. Reprenons notre structure Rectangle et ajoutons deux méthodes, une méthode statique new servant de constructeur et une méthode non statique print permettant d’afficher la longueur et la largeur de nos objets Rectangle :

Utilisons maintenant nos deux méthodes :

Note : Il n’existe pas de concept de constructeur en Rust comme nous avons l’habitude de le voir dans d’autres langages, la méthode statique new vue précédemment est simplement une convention.

Les traits

Il n’existe pas à proprement parler d’héritage en Rust à la place nous avons le concept de trait. Les traits permettent de définir des comportements à partager, mais également des comportements à implémenter comme pour les interfaces des autres langages de programmation. Déclarons un trait Shape avec une méthode area qui devra être implémentée par les structures utilisant ce trait :

La syntaxe pour l’implémentation d’un trait est la suivante impl <trait> for <struct>. Reprenons notre structure Rectangle et implémentons le trait Shape pour celle-ci :

La méthode area peut ensuite être appelée sur les instances de la structure Rectangle :

Il est tout à fait possible pour une structure d’implémenter plusieurs traits. Il reste encore beaucoup de choses à dire à propos des traits, mais cela vous donne déjà une bonne idée de leurs utilisations avec ce petit exemple.

Les modules

Rust propose un système de module permettant de créer des espaces de noms (ou namespace) et d’organiser son code en fichiers et dossiers.

Les espaces de noms

Commençons par voir la première utilisation des modules à savoir la création d’espace de noms. Créons donc un espace de noms http à l’aide du mot-clé mod :

Mais lorsque nous compilons, nous avons l’erreur suivante :

Par défaut toutes les fonctions (ou structures) se trouvant dans un module sont privées. Pour rendre celles-ci publiques il faut utiliser le mot-clé pub :

Il est également possible de rendre toutes les fonctions d’un module publiques en ajoutant le mot-clé pub avant le mot-clé mod :

Séparer son code en plusieurs fichiers

Il est également possible de séparer son code en plusieurs fichiers. Pour cela créons un fichier http.rs et copions notre code, mais cette fois-ci sans utiliser le mot-clé mod :

Importons notre module via le mot-clé mod suivi du nom du fichier (ici http) dans le fichier main.rs, puis utilisons notre fonction request :

Nous pouvons également mettre notre module dans un dossier. L’avantage de cette méthode est qu’il est possible de séparer son code en plusieurs fichiers.

Pour cela il suffit de créer un dossier http et d’ajouter un fichier mod.rs (le nom est très important) contenant le code de notre module. Ajoutons également un fichier status_message.rs contenant une fonction permettant d’obtenir le message de statut d’une requête à partir du code HTTP :

Ce qui nous donne l’arborescence suivante :

Nous venons en fait de créer un nouveau module nommé status_message. Incluons ensuite celui-ci dans notre fichier http.rs :

Nous pouvons maintenant utiliser notre module http ainsi que le sous-module status_message dans notre fichier main.rs :

Il peut-être parfois lourd de devoir écrire les espaces de noms au complet, c’est pourquoi il est possible d’utiliser le mot-clé use. Si l’on reprend notre exemple précédent nous pouvons utiliser l’espace de nom http comme suit :

Cargo

Nous avons fait le tour des bases de Rust, mais il reste un point que j’aimerais vous montrer avant de terminer, il s’agit de l’outil Cargo. Cargo est le système de compilation et de gestion de paquets de Rust.

Pour l’utiliser, il suffit de créer un nouveau projet avec la commande suivante :

Cela crée automatiquement un dépôt Git de votre nouveau projet avec la structure suivante :

Pour le moment, nous n’avons que les fichiers et dossiers suivants :

  • Cargo.toml : Il s’agit du fichier de configuration Cargo de votre projet. Ce fichier est au format TOML (Tom’s Obvious, Minimal Language inventé par Tom Preston-Werner l’un des fondateurs de Github pour la petite info).

Ce fichier est séparé en plusieurs parties :

  • package : Liste l’ensemble des informations concernant votre paquet : le nom, le numéro de version, l’auteur, et l’édition de Rust à utiliser.
  • dependencies : Liste l’ensemble des dépendances du projet que l’on appelle des crates.

D’autres parties existent, mais nous n’allons pas les aborder ici. Vous pouvez néanmoins aller jeter un coup d’œil sur la documentation officielle.

  • src : Le dossier qui contiendra votre code source. Cargo crée automatiquement le point d’entrée de votre programme à savoir le fichier main.rs

Compiler avec Cargo

Plutôt que de passer par la commande rustc pour compiler, il est possible d’utiliser Cargo avec la commande suivante :

Cette commande va permettre de créer l’exécutable de votre programme dans le dossier ./target/debug

Vous remarquerez également qu’un fichier Cargo.lock est créé. Comme pour le fichier package-lock.json d’un projet JavaScript ou Composer.lock d’un projet PHP, celui-ci va permettre de verrouiller les versions des dépendances.

Pour exécuter votre programme, il suffit de lancer la commande suivante :

Cette commande permet également de compiler, si nécessaire, en plus d’exécuter votre programme.

Si vous souhaitez uniquement vérifier que votre code ne contient pas d’erreur de compilation, vous pouvez utiliser la commande suivante :

Cette commande compile votre code sans créer d’exécutable et est donc beaucoup plus rapide que la commande cargo build.

Et la production ?

Comme je l’ai dit, la compilation de notre programme avec la commande cargo build produit un exécutable dans le dossier target/debug. Mais cet exécutable n’est pas optimisé pour la production. Si vous souhaitez distribuer votre programme ou l’utiliser en production, il suffit de lancer la commande cargo build avec l’option release comme ceci :

Ajout de dépendances

Si vous souhaitez ajouter une dépendance à votre projet, il suffit de se rendre sur le site crates.io qui regroupe les modules créés par la communauté Rust et de rechercher ce qui vous intéresse. Une fois trouvé, il suffira de l’ajouter manuellement dans le fichier Cargo.toml dans la partie dependencies. Par exemple si vous souhaitez ajouter la librairie rand permettant de générer des nombres aléatoires, il suffit de l’ajouter comme ceci :

Et de l’utiliser de cette façon dans votre code :

Note : Si la dépendance que vous utilisez n’est utile que pour le développement et non pour la production, vous pouvez l’ajouter dans une nouvelle partie [dev-dependencies]

Si vous souhaitez mettre à jour une dépendance, vous pouvez utiliser la commande suivante :

Pour finir…

Nous avons vu dans cet article uniquement les bases de Rust et nous n’avons qu’effleuré la surface de ce qu’offre Rust tellement le langage est riche. La courbe d’apprentissage est certes ardue, contrairement à d’autres langages, mais le jeu en vaut clairement la chandelle. Si vous souhaitez sortir de votre zone de confort et n’avez pas peur d’apprendre de nouvelles choses, lancez-vous dans l’apprentissage de Rust, cet investissement vous sera bénéfique pour le futur.

J’espère que je vous ai donné envie d’en apprendre un peu plus. Si c’est le cas, je vous invite à lire les ressources disponibles sur le site officiel. Nous, on se retrouve plus tard pour d’autres articles consacrés à Rust.


Annonces partenaire

Je suis lead developer dans une boîte spécialisée dans l'univers du streaming/gaming, et en parallèle, je m'éclate en tant que freelance. Passionné par l'écosystème JavaScript, je suis un inconditionnel de Node.js depuis 2011. J'adore échanger sur les nouvelles tendances et partager mon expérience avec les autres développeurs. Si vous avez envie de papoter, n'hésitez pas à me retrouver sur Twitter, m'envoyer un petit email ou même laisser un commentaire.

7 commentaires

  1. Bonjour, très sympa de trouver un article sur les bases de Rust en Français: merci <3.
    En passant, une petite coquille, il me semble que: 
    «La seconde différence est que le type d’une constante doit également être déclaré i̶m̶[ex]plicitement»

  2. Merci pour cet article. J’avais commencé à me pencher sur la documentation officielle qui est très bien faite mais par manque de temps et sans projet actuellement pour mettre en pratique ce que j’y ai appris, j’ai un peu mis de côté. Mais ton article est un bon résumé.

    Petites coquilles :
    “D’autres langages comme Java ou Python par exemple, résous la plupart des problèmes de mémoire”. => “résolvent”
    “Ouvrez donc votre éditeur préféré, créer un fichier main.rs” => “Ouvrez donc votre éditeur préféré, créez un fichier main.rs”
    “Les variables en Rust sont par défaut immuables (immutables en anglais) c’est-à-dire qu’il n’est pas possible de changer leurs valeurs après leurs déclarations.” => “leur valeur après leur déclaration”
    “Les chaînes de caractères (str) en Rust sont bien plus complexes qu’elles ont en l’air.” => “Les chaînes de caractères (str) en Rust sont bien plus complexes qu’elles en ont l’air.”
    “structures de contrôles” => “structures de contrôle”
    ” (oui il existe certains cas ou une boucle infinie est utile).” => ” (oui il existe certains cas où une boucle infinie est utile).”
    “// Fonction sans paramètres ni valeur de retour
    fn print_hello_world() {” => “// Fonction sans paramètre ni valeur de retour”
    “Pour accéder aux attributs de notre objet, il suffit de spécifier leurs noms, ” => “Pour accéder aux attributs de notre objet, il suffit de spécifier leur nom, ”
    “Cela créer automatiquement un dépôt Git de votre nouveau projet avec la structure suivante :” => “Cela crée automatiquement un dépôt Git de votre nouveau projet avec la structure suivante :”
    “Pour le moment, nous avons que les fichiers et dossiers suivants :” => “Pour le moment, nous n’avons que les fichiers et dossiers suivants :”
    “Cargo créer automatiquement le point d’entrée de votre programme à savoir le fichier main.rs” => “Cargo crée automatiquement le point d’entrée de votre programme à savoir le fichier main.rs”
    “d’un projet PHP, celui-ci va permettent de verrouiller les versions des ” => “d’un projet PHP, celui-ci va permettre de verrouiller les versions des ”
    “Si vous souhaitez uniquement vérifier que votre code ne contient pas d’erreurs de compilation” => “Si vous souhaitez uniquement vérifier que votre code ne contient pas d’erreur de compilation”

  3. Bonsoir et merci pour cet article très intéressant pour une première approche.
    Si j’ai bien compris, les slices se comportent comme en Python, c’est-à-dire que « 0..3 » par exemple prend en compte les éléments 0, 1 et 2 mais en excluant le 3 ?
    Dans ce cas je pense qu’une petite précision au sujet d’un tel « gotcha » serait bienvenue ainsi, peut-être qu’une correction du commentaire de l’exemple lié à « 0..3 ».

    1. Merci pour ton commentaire. Les slices sont une référence sur une partie d’une structure de données comme les tableaux par exemple. L’opérateur “..” se comporte effectivement comme en Python. J’ajouterais prochainement une explication sur ces différents opérateurs.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.