Rust (langage)

Un article de Wikipédia, l'encyclopédie libre.
Sauter à la navigation Sauter à la recherche

Page d'aide sur l'homonymie Pour les articles homonymes, voir Rust et Mozilla.

Rust
Logo.

Date de première version Voir et modifier les données sur Wikidata
Paradigmes Impératif, fonctionnel, concurrent
Auteur Graydon Hoare
Développeurs Mozilla
Dernière version 1.38.0 ()[1]Voir et modifier les données sur Wikidata
Version en développement 0.1 ()[2],[3]Voir et modifier les données sur Wikidata
Typage Fort, Statique
Influencé par C++, Erlang, Haskell, Scala, OCaml, Scheme, Swift, C#, Alef, Limbo[4]
Écrit en RustVoir et modifier les données sur Wikidata
Système d'exploitation Multiplate-forme
Licence Licence Apache version 2.0[5] et licence MIT[5]Voir et modifier les données sur Wikidata
Site web www.rust-lang.orgVoir et modifier les données sur Wikidata
Extension de fichier rs et rlibVoir et modifier les données sur Wikidata

Rust est un langage de programmation compilé multi-paradigme conçu et développé par Mozilla Research[6]. Il a été conçu pour être « un langage sécurisé, concurrent, pratique »[7],[8], supportant les styles de programmation purement fonctionnel, modèle d'acteur, procédural, ainsi qu'orienté objet sous certains aspects[9].

Du fait de la politique de Mozilla[10], Rust est entièrement développé de façon ouverte (les ingénieurs de Mozilla Research publient leurs idées et les décisions prises lors des réunions) et sollicite les remarques et contributions de la communauté. La conception du langage est graduellement améliorée au travers des retours de l'équipe travaillant sur le moteur de rendu Servo[11] et de façon pragmatique lors de l'écriture du compilateur. Bien que le projet soit financé par Mozilla, la majorité des contributions proviennent de la communauté.

Description[modifier | modifier le code]

Le but de Rust est de devenir un langage sûr et concurrent[12].

Le langage peut notamment donner des garanties d'absence d'erreur de segmentation ou de situation de concurrence[13]. De plus, ceci se fait sans ramasse-miettes[14].

Enfin, Rust est accompagné de Cargo, un gestionnaire de paquets permettant de gérer la compilation et les dépendances entre paquets.

Histoire[modifier | modifier le code]

Le langage s'est développé à partir d'un projet personnel de Graydon Hoare, qui commença à travailler dessus en 2006. Son employeur Mozilla commença sa participation en 2009[15] et révéla officiellement ses travaux pour la première fois en 2010[16]. La même année, le projet passa du compilateur initialement utilisé (écrit en OCaml) au compilateur auto-hébergé écrit en Rust[17]. Ce compilateur, connu sous le nom de rustc, s'est compilé avec succès en 2011[18]. Le compilateur auto-hébergé utilise LLVM pour son Backend.

La première version alpha numérotée du compilateur Rust apparait en janvier 2012[19].

La première version stable de Rust, Rust 1.0 est arrivée en 2015.

Caractéristiques[modifier | modifier le code]

Syntaxe[modifier | modifier le code]

La syntaxe du langage est similaire à celle du C, étant constituée de blocs de code délimités par des accolades et de structures de contrôle comme if, else, while et for.

Cependant, la sémantique de Rust est assez différente. En effet, les blocs et les structures de contrôles sont des expressions, comme on peut le voir dans l'exemple :

let x = if n < 10 {
    n
} else {
    n - 10
};

En C, une telle opération n'est pas possible, il faudra soit encapsuler le bloc conditionnel dans une autre fonction, soit utiliser un opérateur ternaire int x = (n < 10) ? n : n - 10;.

Ainsi, dans sa grammaire, le rust se rapproche beaucoup plus des langages fonctionnels comme l'Haskell ou l'OCaml.

Valeur et mutabilité[modifier | modifier le code]

Dans la plupart des langages, une variable est modifiable par défaut. En C par exemple, il faut utiliser le mot clé const pour signaler que la valeur est une constante. Le C++ va encore plus loin avec un mot clé constexprqui déduit la valeur d'une constante à la compilation tout en gardant la vérification du type de la constante.

Rust inverse ce comportement :

Rust crée un statut intermédiaire, celui de "variable immuable" ("immutable variable" en version originale). Les variables, déclarées par let, sont par défaut immuables, il est nécessaire de rajouter le mot clé mut (« mutable » = modifiable) pour rendre une variable "mutable" ou "muable". Les variables immuables ne peuvent être affectée qu'une seule fois.

Enfin, il existe des constantes qui doivent être affectées avec une précision de type et qui doivent être initialisées à partir d'une expression constante, excluant les résultats d'appels de fonctions. [20]

Le mot clé const utilisé en remplacement de let correspond en Rust au mot-clé constexpr de C++ et déclare des "constantes" au sens de Rust.

fn main()
{
    //déclaration
    let mut a = 5; //variable muable "mut"(obligation d'initialiser immédiatement)
    let b = a; //autorisé car b variable

    //constantes
    const c:u32 = 5; // déclaration d'une constante entière non-signée
    //const c:u8 = b - 3; interdit car `b - 3` n'est pas une expression constante
    //const c = 5; interdit car le type de c n'est pas précisé
    
    //altération
    //c = 3; illégal car c constante
    //b = 3; illégal car b variable immuable
    a = 3; 
    a = 2; // autorisé car a est déclaré comme "mut"

    //vérification des valeurs
    assert_eq!(a, 5);
    assert_eq!(b, 5);
}


Énumérations et Filtrage par motif[modifier | modifier le code]

Rust permet la définition de types sommes (ou énumérations) à l'aide du mot-clé enum. On peut utiliser ces types sommes avec du filtrage par motif, en utilisant par exemple le mot-clé match.

Exemple :

// On crée un type « Forme » pour décrire des formes géométriques.
enum Forme {
    Point,               // une forme peut être un point, sans données attachées.
    Rectangle(f64, f64), // une forme peut être un rectangle, caractérisé par les longueurs de ses côtés.
    Cercle(f64),         // une forme peut être un cercle, caractérisé par son rayon.
}

// Calcule l'aire d'une forme géométrique.
fn aire(f: Forme) -> f64 {
    match f { // Filtrage par motif avec « match »
        Forme::Point => 0.0,
        Forme::Cercle(rayon) => 3.14 * rayon * rayon,
        Forme::Rectangle(cote_a, cote_b) => cote_a * cote_b,
    }
}

Certaines énumérations font partie de la bibliothèque standard, comme Option, permettant d'éviter l'utilisation du pointeur NULL[21].

Ownership et Borrowing[modifier | modifier le code]

Pour obtenir des garanties de sûreté, Rust utilise les concepts d'ownership (propriété) et de borrowing (emprunt).

Ainsi, une valeur a toujours un seul propriétaire. Si la valeur change de propriétaire, l'ancien propriétaire ne peut plus l'utiliser.

Par exemple :

 1 fn take_ownership(v: Vec<i32>) {
 2     // Cette fonction prend la propriété de son paramètre v et ne la rend pas.
 3     println!("{:?}", v);
 4 }
 5 
 6 fn main() {
 7     let mut a = vec![1, 2, 3]; // a est le propriétaire du vecteur.
 8     let mut b = a;             // b est maintenant le propriétaire du vecteur.
 9     a.push(4);                 // erreur de compilation : a n'a plus le droit d'utiliser ce vecteur
10     take_ownership(b);
11     b.push(5);                 // erreur de compilation : b n'a plus le droit d'utiliser ce vecteur
12 }

Pour utiliser une valeur à plusieurs endroits à la fois, il est possible de prêter cette valeur en créant des références. Il est possible de créer :

  • Soit des références immuables, avec l'opérateur &.
  • Soit une référence muable, avec l'opérateur & mut.

En particulier, il n'est pas possible de mélanger les références muables et immuables.

Exemple :

 1 fn take_reference(v: &Vec<i32>) {
 2     // Cette fonction prend une référence vers un vecteur
 3     println!("{:?}", v);
 4 }
 5 
 6 fn correct() {
 7     let a = vec![1, 2, 3];
 8     let ref_1 = &a;
 9     let ref_2 = &a;
10     // On crée plusieurs références immuables vers a que l'on peut passer à des fonctions.
11     // Faire ceci ne serait pas possible si l'on travaillait avec une fonction qui prend
12     // l'ownership de a.
13     take_reference(ref_1);
14     take_reference(ref_2);
15 }
16 
17 fn incorrect() {
18     let mut a = vec![1, 2, 3];
19     // Ce code ne compile pas.
20     // En effet, on travaille à la fois avec une référence muable vers a (ref_1),
21     // et à la fois avec une référence immuable vers a (ref_2).
22     let ref_1 = &mut a[0];
23     let ref_2 = &a;
24     println!("{}", *ref_1);
25     take_reference(ref_2);
26 }

Points forts[modifier | modifier le code]

Rust repose sur des concepts connus et éprouvés (d'où le nom Rust, « la rouille » en anglais) et n'intègre pas de concepts nouveaux et non testés[22][réf. obsolète][23]. Ces concepts ont été empruntés à des langages de programmation existants et assemblés dans un seul langage[24] :

Rust est souvent décrit comme l'un des successeurs potentiels de C++[25] (avec D et, dans une moindre mesure, Go) notamment grâce à sa sûreté — c'est un objectif clairement affiché par les développeurs.

Projets basés sur Rust[modifier | modifier le code]

Exemples de code[modifier | modifier le code]

Hello world :

1 // This is the main function
2 fn main() {
3     // The statements here will be executed when the compiled binary is called
4 
5     // Print text to the console
6     println!("Hello World!");
7 }

Arrays and Slices :

 1 use std::mem;
 2 
 3 // This function borrows a slice
 4 fn analyze_slice(slice: &[i32]) {
 5     println!("first element of the slice: {}", slice[0]);
 6     println!("the slice has {} elements", slice.len());
 7 }
 8 
 9 fn main() {
10     // Fixed-size array (type signature is superfluous)
11     let xs: [i32; 5] = [1, 2, 3, 4, 5];
12 
13     // All elements can be initialized to the same value
14     let ys: [i32; 500] = [0; 500];
15 
16     // Indexing starts at 0
17     println!("first element of the array: {}", xs[0]);
18     println!("second element of the array: {}", xs[1]);
19 
20     // `len` returns the size of the array
21     println!("array size: {}", xs.len());
22 
23     // Arrays are stack allocated
24     println!("array occupies {} bytes", mem::size_of_val(&xs));
25 
26     // Arrays can be automatically borrowed as slices
27     println!("borrow the whole array as a slice");
28     analyze_slice(&xs);
29 
30     // Slices can point to a section of an array
31     println!("borrow a section of the array as a slice");
32     analyze_slice(&ys[1 .. 4]);
33 
34     // Out of bound indexing yields a panic
35     println!("{}", xs[5]);
36 }

Annexes[modifier | modifier le code]

Liens externes[modifier | modifier le code]

Références[modifier | modifier le code]

  1. « https://blog.rust-lang.org/2019/09/26/Rust-1.38.0.html »
  2. « https://mail.mozilla.org/pipermail/rust-dev/2012-January/001256.html »
  3. « Release 0.1 » (consulté le 23 juillet 2018)
  4. https://doc.rust-lang.org/stable/reference/influences.html
  5. a et b « https://github.com/rust-lang/rust/blob/master/COPYRIGHT »
  6. (en) « The Rust Language », Lambda the Ultimate, (consulté le 30 octobre 2010).
  7. (en) « The Rust Programming Language » (consulté le 21 octobre 2012).
  8. (en) « Doc language FAQ » (consulté le 21 octobre 2012).
  9. https://doc.rust-lang.org/book/ch17-01-what-is-oo.html
  10. (en) « The Mozilla Manifesto » (consulté le 9 avril 2012).
  11. (en) Peter Bright, « Samsung teams up with Mozilla to build browser engine for multicore machines », (consulté le 4 avril 2013).
  12. https://www.rust-lang.org/fr-FR/faq.html#what-is-this-projects-goal
  13. https://doc.rust-lang.org/nomicon/what-unsafe-does.html
  14. https://www.rust-lang.org/en-US/faq.html#is-rust-garbage-collected
  15. (en) « Project FAQ », (consulté le 11 janvier 2012).
  16. (en) « Future Tense », (consulté le 6 février 2012) : « At Mozilla Summit 2010, we launched Rust, a new programming language motivated by safety and concurrency for parallel hardware, the “manycore” future which is upon us. »
  17. (en) Graydon Hoare, « Rust Progress » [archive du ], (consulté le 30 octobre 2010).
  18. (en) Graydon Hoare, « [rust-dev] stage1/rustc builds », (consulté le 20 avril 2011) : « After that last change fixing the logging scope context bug, looks like stage1/rustc builds. Just shy of midnight :) ».
  19. (en) catamorphism, « Mozilla and the Rust community release Rust 0.1 (a strongly-typed systems programming language with a focus on memory safety and concurrency) », (consulté le 6 février 2012).
  20. « Variables and Mutability - The Rust Programming Language », sur doc.rust-lang.org (consulté le 5 juillet 2019)
  21. https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html#the-option-enum-and-its-advantages-over-null-values
  22. « Présentation de Rust sur Léa-Linux » (consulté le 11 décembre 2013).
  23. (en) Nicholas Matsakis et Aaron Turon, « Préambule » (consulté le 12 juin 2019)
  24. « Sortie de Rust 0.8 » (consulté le 15 octobre 2013).
  25. Vincent Hermann, « Microsoft se penche sur le langage Rust pour sa programmation système » (consulté le 26 juillet 2019)
  26. « Shipping Rust in Firefox ★ Mozilla Hacks – the Web developer blog », sur hacks.mozilla.org (consulté le 19 octobre 2016)
  27. (en-US) Cade Metz, « The Epic Story of Dropbox’s Exodus From the Amazon Cloud Empire », WIRED,‎ (lire en ligne, consulté le 19 octobre 2016)
  28. (en) « Rust NPM whitepaper », The Rust Project Developers,‎ (lire en ligne)
  29. (en-US) Boyd Johnson, « Safety, Performance and Innovation: Rust in Hyperledger Sawtooth », (consulté le 26 août 2019)