Rust (langage de programmation) - Rust (programming language)

Rouiller
Une lettre R majuscule dans un pignon
Le logo officiel de Rust
Paradigmes Multi-paradigme : concurrent , fonctionnel , générique , impératif , structuré
Conçu par Graydon Hoare
Développeur La Fondation de la rouille
Première apparition 7 juillet 2010 ; il y a 11 ans ( 2010-07-07 )
Version stable
1.57.0  Modifiez ceci sur Wikidata / 2 décembre 2021 ; il y a 29 jours ( 2 décembre 2021 )
Discipline de frappe Affine , inférée , nominale , statique , forte
Langage d'implémentation Rouiller
Plate-forme AMD64 , i686 , arm , AArch64 , armv7 , mips , mips64 , mipsel , mips64el , powerpc , powerpc64 , powerpc64le , risc-v , s390x , WebAssembly
Système d'exploitation Windows , Linux , macOS , FreeBSD , NetBSD , Illumos , Haiku , Android , Redox , iOS , Fuchsia
Licence MIT ou Apache 2.0
Extensions de nom de fichier .rs, .rlib
Site Internet www .rust-lang .org
Influencé par
Influencé

Rust est un multi-paradigme , langage de programmation à usage général conçu pour la performance et la sécurité , en particulier la sécurité concurrency . Rust est syntaxiquement similaire à C++ , mais peut garantir la sécurité de la mémoire en utilisant un vérificateur d'emprunt pour valider les références . Rust assure la sécurité de la mémoire sans récupération de place et le comptage des références est facultatif. Rust a été appelé un langage de programmation système et en plus des fonctionnalités de haut niveau telles que la programmation fonctionnelle, il offre également des mécanismes de gestion de la mémoire de bas niveau .

Rust a été conçu à l'origine par Graydon Hoare de Mozilla Research, avec des contributions de Dave Herman, Brendan Eich et d'autres. Les concepteurs ont affiné le langage en écrivant le moteur de navigateur expérimental Servo et le compilateur Rust . Il est de plus en plus utilisé dans l'industrie et Microsoft a expérimenté le langage pour les composants logiciels sécurisés et critiques pour la sécurité.

Rust a été élu "langage de programmation le plus apprécié" dans le Stack Overflow Developer Survey chaque année depuis 2016, bien qu'il n'ait été utilisé que par 7 % des personnes interrogées en 2021.

Histoire

Un exemple de compilation d'un programme Rust

La langue est née d'un projet personnel commencé en 2006 par Graydon Hoare, employé de Mozilla. Hoare a déclaré que le projet portait peut-être le nom de champignons de la rouille et que le nom est également une sous-chaîne de « robuste ». Mozilla a commencé à sponsoriser le projet en 2009 et l'a annoncé en 2010. La même année, le travail est passé du compilateur initial (écrit en OCaml ) à un compilateur auto-hébergé basé sur LLVM écrit en Rust. Nommé rustc , il s'est compilé avec succès en 2011.

La première version pré-alpha numérotée du compilateur Rust a eu lieu en janvier 2012. Rust 1.0, la première version stable, a été publiée le 15 mai 2015. Après 1.0, les versions ponctuelles stables sont livrées toutes les six semaines, tandis que les fonctionnalités sont développées tous les soirs. Rust avec des versions quotidiennes, puis testé avec des versions bêta qui durent six semaines. Tous les 2 à 3 ans, une nouvelle "Edition" Rust est produite. Il s'agit de fournir un point de référence facile pour les modifications dues à la nature fréquente du calendrier de publication de Rust's Train, ainsi que de fournir une fenêtre pour apporter des modifications de rupture. Les éditions sont largement compatibles.

En plus du typage statique conventionnel , avant la version 0.4, Rust prenait également en charge les typesstates . Le système typestate modélisait les assertions avant et après les instructions du programme, grâce à l'utilisation d'une checkinstruction spéciale . Des divergences pourraient être découvertes au moment de la compilation , plutôt qu'au moment de l' exécution , comme cela pourrait être le cas avec les assertions dans le code C ou C++. Le concept d'état de type n'était pas unique à Rust, car il a été introduit pour la première fois dans le langage NIL . Les états de type ont été supprimés car en pratique ils étaient peu utilisés, bien que la même fonctionnalité puisse être obtenue en tirant parti de la sémantique de déplacement de Rust .

Le style du système d'objets a considérablement changé dans les versions 0.2, 0.3 et 0.4 de Rust. La version 0.2 a introduit les classes pour la première fois, et la version 0.3 a ajouté plusieurs fonctionnalités, notamment les destructeurs et le polymorphisme via l'utilisation d'interfaces. Dans Rust 0.4, des traits ont été ajoutés comme moyen de fournir l' héritage ; les interfaces ont été unifiées avec des traits et supprimées en tant que fonctionnalité distincte. Les classes ont également été supprimées et remplacées par une combinaison d'implémentations et de types structurés .

À partir de Rust 0.9 et jusqu'à Rust 0.11, Rust avait deux types de pointeurs intégrés : ~et @, simplifiant le modèle de mémoire de base . Il a réimplémenté ces types de pointeur dans la bibliothèque standard en tant que Boxand (maintenant supprimé) Gc.

En janvier 2014, avant la première version stable, Rust 1.0, le rédacteur en chef de Dr. Dobb's , Andrew Binstock, a commenté les chances de Rust de devenir un concurrent du C++ et des autres langages émergents D , Go , et Nim (alors Nimrod). Selon Binstock, alors que Rust était « largement considéré comme un langage remarquablement élégant », l'adoption a ralenti car il changeait à plusieurs reprises entre les versions.

Rust a une interface de fonction étrangère (FFI) qui peut être appelée depuis, par exemple, le langage C, et peut appeler C. Bien qu'appeler C++ ait toujours été difficile (depuis n'importe quel langage), Rust a une bibliothèque, CXX, pour permettre d'appeler ou de C++, et "CXX a une surcharge nulle ou négligeable."

En août 2020, Mozilla a licencié 250 de ses 1 000 employés dans le monde dans le cadre d'une restructuration d'entreprise causée par l'impact à long terme de la pandémie de COVID-19 . Parmi les personnes licenciées figuraient la plupart des membres de l'équipe Rust, tandis que l'équipe Servo était complètement dissoute. L'événement a soulevé des inquiétudes quant à l'avenir de Rust.

La semaine suivante, l'équipe Rust Core a reconnu le grave impact des licenciements et a annoncé que des plans pour une fondation Rust étaient en cours. Le premier objectif de la fondation serait de s'approprier toutes les marques et noms de domaine , et d'assumer également la responsabilité financière de leurs coûts.

Le 8 février 2021, la formation de la Rust Foundation a été officiellement annoncée par ses cinq sociétés fondatrices ( AWS , Huawei , Google , Microsoft et Mozilla).

Le 6 avril 2021, Google a annoncé la prise en charge de Rust dans Android Open Source Project comme alternative à C/C++.

Syntaxe

Voici un "Hello, World!" programme écrit en Rust. La println! macro imprime le message sur la sortie standard .

fn main() {
    println!("Hello, World!");
}

La syntaxe de rouille est similaire à C et C ++ , avec des blocs de code délimité par des accolades , et le contrôle de flux des mots clés tels que if, else, whileet for, bien que la syntaxe spécifique pour la définition des fonctions est plus semblable à Pascal . Malgré la ressemblance syntaxique avec C et C++, la sémantique de Rust est plus proche de celle de la famille de langages ML et du langage Haskell . Presque chaque partie d'un corps de fonction est une expression , même des opérateurs de flux de contrôle. Par exemple, l' ifexpression ordinaire remplace également le conditionnel ternaire de C , un idiome utilisé par ALGOL 60 . Comme dans Lisp , une fonction n'a pas besoin de se terminer par une returnexpression : dans ce cas, si le point-virgule est omis, la dernière expression de la fonction crée la valeur de retour , comme le montre l' implémentation récursive suivante de la fonction factorielle :

fn factorial(i: u64) -> u64 {
    match i {
        0 => 1,
        n => n * factorial(n-1)
    }
}

L' implémentation itérative suivante utilise l' ..=opérateur pour créer une plage inclusive :

fn factorial(i: u64) -> u64 {
    (2..=i).product()
}

Des fonctionnalités plus avancées dans Rust incluent l'utilisation de fonctions génériques pour réaliser le polymorphisme de type . Ce qui suit est un programme Rust pour calculer la somme de deux choses, pour lesquelles l'addition est implémentée, en utilisant une fonction générique :

use std::ops::Add;

fn Sum<T: Add<Output = T> + Copy> (num1: T, num2: T) -> T {
    num1 + num2
}

fn main() {
    let result1 = Sum(10,20);
    println!("Sum is: {:?}", result1);
    
    let result2 = Sum(10.23,20.45);
    println!("Sum is: {:?}", result2);
}

Caractéristiques

Une présentation sur Rust par Emily Dunham de l' équipe Rust de Mozilla ( conférence linux.conf.au , Hobart, 2017)

Rust est destiné à être un langage pour les systèmes hautement concurrents et hautement sécurisés , et la programmation dans le grand , c'est-à-dire la création et le maintien de limites qui préservent l'intégrité du grand système. Cela a conduit à un ensemble de fonctionnalités mettant l'accent sur la sécurité, le contrôle de la disposition de la mémoire et la simultanéité .

Sécurité de la mémoire

Rust est conçu pour protéger la mémoire . Il n'autorise pas les pointeurs nuls , les pointeurs pendants ou les courses de données . Les valeurs de données ne peuvent être initialisées que via un ensemble fixe de formulaires, qui nécessitent tous que leurs entrées soient déjà initialisées. Pour répliquer des pointeurs valides ou NULL, comme dans les structures de données de liste chaînée ou d' arborescence binaire , la bibliothèque principale de Rust fournit un type d' option , qui peut être utilisé pour tester si un pointeur a une valeur ou . Rust a ajouté une syntaxe pour gérer les durées de vie , qui sont vérifiées au moment de la compilation par le vérificateur d'emprunt . Un code dangereux peut subvertir certaines de ces restrictions à l'aide du mot - clé. SomeNoneunsafe

Gestion de la mémoire

Rust n'utilise pas le ramasse-miettes automatisé . La mémoire et les autres ressources sont gérées via l' acquisition de ressources selon la convention d' initialisation , avec un comptage de références facultatif . Rust fournit une gestion déterministe des ressources, avec une surcharge très faible . Rust favorise l' allocation des valeurs par pile et n'effectue pas de boxing implicite .

Il y a le concept de références (à l'aide du &symbole), qui n'implique pas le comptage de références à l'exécution. La sécurité de ces pointeurs est vérifiée au moment de la compilation, empêchant les pointeurs pendants et d'autres formes de comportement indéfini . Le système de types de Rust sépare les pointeurs partagés et immuables du formulaire &Tdes pointeurs uniques et mutables du formulaire &mut T. Un pointeur mutable peut être contraint à un pointeur immuable, mais pas l'inverse.

La possession

Rust a un système de propriété où toutes les valeurs ont un propriétaire unique, et la portée de la valeur est la même que la portée du propriétaire. Les valeurs peuvent être passées par référence immuable, à l'aide de &T, par référence mutable, à l'aide de &mut T, ou par valeur, à l'aide de T. À tout moment, il peut y avoir soit plusieurs références immuables, soit une seule référence mutable (un verrou de lecture-écriture implicite ). Le compilateur Rust applique ces règles au moment de la compilation et vérifie également que toutes les références sont valides.

Types et polymorphisme

Le système de types de Rust prend en charge un mécanisme appelé traits , inspiré des classes de types du langage Haskell . Les traits annotent les types et sont utilisés pour définir un comportement partagé entre différents types : par exemple, les flottants et les entiers peuvent tous deux implémenter un trait « Ajouter » car ils peuvent tous les deux être ajoutés ; et tout type pouvant être imprimé sous forme de chaîne implémente les traits « Affichage » ou « Débogage ». Cette facilité est connue sous le nom de polymorphisme ad hoc .

Rust utilise l' inférence de type pour les variables déclarées avec le mot - clélet . De telles variables ne nécessitent pas qu'une valeur soit initialement affectée pour déterminer leur type. Une erreur de compilation se produit si une branche de code quitte la variable sans affectation. Les variables affectées plusieurs fois doivent être marquées avec le mot-clé mut(abréviation de mutable).

Une fonction peut recevoir des paramètres génériques , ce qui permet d'appliquer la même fonction à différents types. Les fonctions génériques peuvent contraindre le type générique à implémenter un ou plusieurs traits particuliers ; par exemple, une fonction « ajouter un » peut nécessiter que le type implémente « Ajouter ». Cela signifie qu'une fonction générique peut être vérifiée de type dès qu'elle est définie.

L'implémentation des génériques Rust est similaire à l'implémentation typique des modèles C++ : une copie distincte du code est générée pour chaque instanciation. C'est ce qu'on appelle la monomorphisation et contraste avec le schéma d' effacement de type généralement utilisé en Java et Haskell. L'effacement de type de Rust est également disponible en utilisant le mot-clé dyn. L'avantage de la monomorphisation est un code optimisé pour chaque cas d'utilisation spécifique ; l'inconvénient est l'augmentation du temps de compilation et de la taille des binaires résultants.

Dans Rust, les types définis par l'utilisateur sont créés avec le structmot - clé. Ces types contiennent généralement des champs de données comme des objets ou des classes dans d'autres langages. Le implmot-clé peut définir des méthodes pour la structure (les données et la fonction sont définies séparément dans une structure) ou implémenter un trait pour la structure. Un trait est un contrat selon lequel une structure a mis en œuvre certaines méthodes requises. Les traits sont utilisés pour restreindre les paramètres génériques et parce que les traits peuvent fournir une structure avec plus de méthodes que celles définies par l'utilisateur. Par exemple, le trait Iteratorrequiert que la nextméthode soit définie pour le type. Une fois la nextméthode définie, le trait fournit des méthodes d'assistance fonctionnelles communes sur l'itérateur comme mapou filter.

Le système d'objets au sein de Rust est basé sur des implémentations, des traits et des types structurés. Les implémentations remplissent un rôle similaire à celui des classes dans d'autres langages et sont définies avec le mot-clé impl. Les traits fournissent l'hérédité et le polymorphisme ; ils permettent des méthodes à définir et mélangés dans des mises en œuvre. Les types structurés sont utilisés pour définir les champs. Les implémentations et les traits ne peuvent pas définir les champs eux-mêmes, et seuls les traits peuvent fournir l'héritage. Entre autres avantages, cela évite le problème du diamant de l' héritage multiple , comme en C++. En d'autres termes, Rust prend en charge l'héritage d'interface mais remplace l'héritage d'implémentation par la composition ; voir la composition sur l'héritage .

Composants

Rust comporte un grand nombre de composants qui étendent l'ensemble des fonctionnalités de Rust et facilitent le développement de Rust. L'installation des composants est généralement gérée par rustup, un programme d' installation de la chaîne d'outils Rust développé par le projet Rust.

Cargaison

Cargo est le système de construction et le gestionnaire de paquets de Rust . Cargo gère le téléchargement des dépendances et la création de dépendances. Cargo agit également comme un emballage pour les composants clippy et autres Rust. Cela nécessite que les projets suivent une certaine structure de répertoires.

Les dépendances d'un package Rust sont spécifiées dans un Cargo. toml avec les exigences de version , indiquant à Cargo quelles versions de la dépendance sont compatibles avec le package. Par défaut, Cargo tire ses dépendances du registre crates.io fourni par l'utilisateur, mais les référentiels et packages Git du système de fichiers local peuvent également être spécifiés en tant que dépendances.

Rustfmt

Rustfmt est un formateur de code pour Rust. Il prend le code source de Rust en entrée et modifie les espaces et l' indentation pour produire du code formaté conformément au guide de style Rust ou aux règles spécifiées dans un fichier rustfmt.toml. Rustfmt peut être invoqué en tant que programme autonome ou sur un projet Rust via Cargo.

Clippy

Clippy est l' outil de linting intégré de Rust pour améliorer l'exactitude, les performances et la lisibilité du code Rust. Il a été créé en 2014 et nommé d'après la fonctionnalité éponyme de Microsoft Office . Depuis 2021, Clippy compte plus de 450 règles, qui peuvent être consultées en ligne et filtrées par catégorie. Certaines règles sont désactivées par défaut.

RLS

RLS est un serveur de langage qui fournit aux IDE et aux éditeurs de texte plus d'informations sur un projet Rust. Il fournit des contrôles de linting via Clippy , un formatage via Rustfmt, la complétion automatique du code via Racer , entre autres fonctions. Le développement de Racer a été ralenti au profit de l' analyseur de rouille .

Extensions de langue

Il est possible d'étendre le langage Rust en utilisant le mécanisme de macro procédural.

Les macros procédurales utilisent des fonctions Rust qui s'exécutent au moment de la compilation pour modifier le flux de jetons du compilateur. Cela complète le mécanisme de macro déclarative (également connu sous le nom de macros par exemple ), qui utilise la correspondance de modèles pour atteindre des objectifs similaires.

Les macros procédurales sont disponibles en trois versions :

  • Macros de type fonction custom!(...)
  • Dériver des macros #[derive(CustomDerive)]
  • Macros d'attributs #[custom_attribute]

La println!macro est un exemple de macro de type fonction et serde_deriveest une bibliothèque couramment utilisée pour générer du code pour lire et écrire des données dans de nombreux formats tels que JSON . Les macros d'attributs sont couramment utilisées pour les liaisons de langage telles que la extendrbibliothèque pour les liaisons Rust à R .

Le code suivant montre l'utilisation du Serialize, Deserializeet Debugdérivent des macros de procédure à mettre en œuvre la lecture et l' écriture JSON ainsi que la possibilité de formater une structure pour le débogage.

use serde_json::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let point = Point { x: 1, y: 2 };

    let serialized = serde_json::to_string(&point).unwrap();
    println!("serialized = {}", serialized);

    let deserialized: Point = serde_json::from_str(&serialized).unwrap();
    println!("deserialized = {:?}", deserialized);
}

Performance

Rust vise "à être aussi efficace et portable que le C++ idiomatique , sans sacrifier la sécurité". Étant donné que Rust utilise LLVM , toutes les améliorations de performances dans LLVM sont également transférées à Rust.

Adoption

Une icône de crabe orange vif
Certains utilisateurs de Rust se désignent eux-mêmes sous le nom de Rustaceans (un jeu de mots sur un crustacé ) et utilisent Ferris comme mascotte non officielle.


Rust a été adopté par de grandes sociétés d'ingénierie logicielle. Par exemple, Dropbox est maintenant écrit en Rust ainsi que certains composants chez Amazon , Facebook , Discord et la Fondation Mozilla . Rust était le troisième langage de programmation le plus apprécié dans l'enquête annuelle Stack Overflow de 2015 et a pris la première place pour la période 2016-2021.

Navigateurs et services Web

  • OpenDNS utilise Rust dans deux de ses composants.
  • Figma , un éditeur de graphiques vectoriels basé sur le Web, est écrit en Rust.

Systèmes d'exploitation

  • Redox est un "système d'exploitation à part entière de type Unix" comprenant un micronoyau écrit en Rust.
  • Theseus, un système d'exploitation expérimental à "conception intralingue", est écrit en Rust.
  • Le système d'exploitation basé sur les capacités de Google Fuchsia dispose de certains outils écrits en Rust.
  • exa est une alternative en ligne de commande Unix/Linux à ls écrit en Rust.

Autres projets et plateformes notables

  • Discord utilise Rust pour des parties de son backend, ainsi que l'encodage vidéo côté client, pour augmenter l'infrastructure de base écrite en Elixir .
  • Microsoft Azure IoT Edge, une plate-forme utilisée pour exécuter les services Azure et l'intelligence artificielle sur les appareils IoT, a des composants implémentés dans Rust.
  • Amethyst et Bevy sont des moteurs de jeu basés sur les données et construits dans Rust.
  • Ruffle est un émulateur SWF open source écrit en Rust.

Gouvernance

Fond de rouille
Logo de la Fondation contre la rouille.png
Formation 8 février 2021 ; il y a 10 mois ( 2021-02-08 )
Fondateurs
Taper Organisation à but non lucratif
Emplacement
Shane Miller
Rébecca Rumbul
Site Internet fondation .rust-lang .org

La rouille Fondation est un but non lucratif organisation de membres incorporés dans le Delaware , États-Unis , les principaux objectifs de soutenir le maintien et le développement de la langue, la culture des membres de l' équipe du projet de Rust et des communautés d'utilisateurs, la gestion de l'infrastructure technique sous - jacente au développement de la rouille , et la gestion et la gestion de la marque Rust.

Il a été créé le 8 février 2021 avec cinq membres fondateurs (Amazon Web Services, Huawei, Google, Microsoft et Mozilla). Le conseil d'administration de la fondation est présidé par Shane Miller. À partir de fin 2021, sa directrice exécutive et PDG est Rebecca Rumbul. Avant cela, Ashley Williams était directrice exécutive par intérim.

Développement

Les conférences Rust incluent :

  • RustConf : une conférence annuelle à Portland, Oregon . Tenue annuellement depuis 2016 (sauf en 2020 et 2021 en raison de la pandémie de COVID-19 ).
  • Rust Belt Rust : une conférence #rustlang dans la Rust Belt
  • RustFest : la conférence européenne @rustlang
  • RustCon Asie
  • Rouille LATAM
  • Oxyder Global

Voir également

Remarques

Les références

Liens externes