Pour mémoire, un trait est un agrégat de méthodes définies pour un type inconnu : Self. Elles peuvent accéder aux autres méthodes déclarées dans le même trait. Les traits peuvent être implémentés pour n'importe quel type de donnée. Dans l'exemple ci-dessous, nous définissons Animal, un groupe de méthodes. Le trait Animal est alors implémenté pour le type Sheep, permettant l'utilisation des méthodes de Animal avec une instance du type Sheep.
Code Rust : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | struct Sheep { naked: bool, name: &'static str } trait Animal { // Méthode statique; `Self` fait référence au type ayant implémenté // le trait. fn new(name: &'static str) -> Self; // Méthode d'instance; Elles renverront une chaîne de caractères. fn name(&self) -> &'static str; fn noise(&self) -> &'static str; // Les traits peuvent fournir une implémentation par défaut. fn talk(&self) { println!("{} says {}", self.name(), self.noise()); } } impl Sheep { fn is_naked(&self) -> bool { self.naked } fn shear(&mut self) { if self.is_naked() { // Les méthodes de `Self` peuvent utiliser les méthodes déclarées // par le trait. println!("{} is already naked...", self.name()); } else { println!("{} gets a haircut!", self.name); self.naked = true; } } } // Implémentation des services du trait `Animal` // pour le type `Sheep`. impl Animal for Sheep { // En l'occurrence, `Self` fait référence à `Sheep`. fn new(name: &'static str) -> Sheep { Sheep { name: name, naked: false } } fn name(&self) -> &'static str { self.name } fn noise(&self) -> &'static str { if self.is_naked() { "baaaaah?" } else { "baaaaah!" } } // L'implémentation par défaut fournie par le trait // peut être réécrite. fn talk(&self) { // Par exemple, nous pourrions fournir une description plus précise. println!("{} pauses briefly... {}", self.name, self.noise()); } } fn main() { // Typer l'identificateur est nécessaire dans ce cas de figure. let mut dolly: Sheep = Animal::new("Dolly"); // TODO ^ Essayez de supprimer le type annoté. dolly.talk(); dolly.shear(); dolly.talk(); } |
Il n'est guère surprenant que les innovations soient plutôt gérables : l'équipe se concentre actuellement principalement sur la prochaine édition de Rust 2021, qui devrait paraître avec l'avant-dernière version le 21 octobre. La phase de test public pour la troisième édition après Rust 2015 et Rust 2018 a récemment commencé.
Les attributs peuvent invoquer des macros de type fonction
Rust 1.54 prend en charge l'invocation de macros de type fonction dans les attributs. Les macros de type fonction peuvent être soit des macros basées sur macro_rules !, soit des macros procédurales qui sont invoquées comme macro!(...). Un cas d'utilisation notable pour cela est l'inclusion de la documentation d'autres fichiers dans les commentaires de la documentation Rust. Par exemple, si le fichier README de votre projet représente un bon commentaire de documentation, vous pouvez utiliser include_str ! pour incorporer directement le contenu. Auparavant, diverses solutions de contournement autorisaient des fonctionnalités similaires, mais à partir de Rust 1.54, les choses sont beaucoup plus ergonomiques.
Code Rust : | Sélectionner tout |
#![doc = include_str!("README.md")]
Des macros peuvent également être imbriquées dans l'attribut, par exemple pour inclure du contenu généré par un script de build :
Code Rust : | Sélectionner tout |
1 2 | #[path = concat!(env!("OUT_DIR"), "/generated.rs")] mod generated; |
Syntaxe acceptée : L'analyseur accepte les expressions Rust arbitraires dans cette position, mais toute expression autre qu'une invocation de macro conduira finalement à une erreur car elle n'est pas attendue par les formes d'expression intégrées (par exemple, #[doc]). Notez que les décorateurs et autres peuvent être en mesure d'observer d'autres formes d'expression.
La compilation incrémentielle est réactivée par défaut
La compilation incrémentielle a été réactivée par défaut dans cette version, après avoir été désactivée par défaut dans la 1.52.1.
Dans Rust 1.52, une validation supplémentaire a été ajoutée lors du chargement des données de compilation incrémentielle à partir du cache sur disque. Cela a entraîné la découverte d'un certain nombre de problèmes potentiels préexistants, car la validation a transformé ces bogues silencieux en erreurs de compilateur internes (ICE - Internal Compiler Errors). En réponse, l'équipe de compilation a décidé de désactiver la compilation incrémentielle dans le correctif 1.52.1, permettant aux utilisateurs d'éviter de rencontrer les ICE et les problèmes sous-jacents, au détriment de temps de compilation plus longs.
Depuis lors, les responsables du développement de Rust ont mené une série de rétrospectives et les contributeurs ont travaillé dur pour résoudre les problèmes signalés, certains correctifs arrivant dans la 1.53 et la majorité dans cette version.
Il existe actuellement encore deux problèmes connus qui peuvent entraîner un ICE. En raison de l'absence de rapports de plantage automatisés, les responsables indiquent ne pas être en mesure de déterminer l'ampleur de l'impact des problèmes en suspens. Cependant, sur la base des commentaires qu'ils ont reçus des utilisateurs concernés par la version 1.52, ils pensent que les problèmes restants sont rares dans la pratique.
Par conséquent, la compilation incrémentielle a été réactivée dans cette version !
Stabilisation des fonctions intégrées wasm32
Une autre nouveauté est la migration de certaines fonctions intégrées sur la plateforme wasm32 vers des versions stables.
La version actuelle stabilise certaines fonctions intrinsèques de la plateforme wasm32 avec lesquelles les instructions SIMD (Single Instruction, Multiple Data) peuvent être implémentées. Cela signifie que pour la plupart des fonctions intrinsèques, wasm32. Contrairement aux fonctions intégrées x86 et x86_64 déjà stabilisées, elles n'ont pas d'exigences de sécurité qui ne peuvent être appelées que si les fonctionnalités de ciblage appropriées sont activées. En effet, WebAssembly valide le code en toute sécurité avant l'exécution, garantissant que les instructions sont décodées correctement ou pas du tout.
Certaines fonctions telles que v128_bitselect sont donc considérées comme des fonctions sûres. D'autres cependant, comme v128_load, sont déclarées comme n'étant pas sûres car elles utilisent des pointeurs bruts.
API stabilisées
Les méthodes et implémentations de traits suivantes ont été stabilisées :
- BTreeMap::into_keys
- BTreeMap::into_values
- HashMap::into_keys
- HashMap::into_values
- arch::wasm32
- VecDeque::binary_search
- VecDeque::binary_search_by
- VecDeque::binary_search_by_key
- VecDeque::partition_point
Source : blog Rust
Voir aussi :
Le projet Tor envisage de remplacer sa base de code C « complexe et fragile » par du Rust dans le cadre du projet Arti : le langage C est-il adapté à la création d'applications sécurisées ?
Les derniers correctifs du projet Rust for Linux montrent que le langage Rust avance à grands pas vers le noyau, Torvalds estime que cela pourrait être prêt pour la version 5.14
Projet Protissimo : l'Internet Security Research Group veut sécuriser la mémoire du noyau Linux avec Rust et fournit au dev Miguel Ojeda un contrat d'un an pour travailler dessus à plein temps
Le créateur de Python, Guido van Rossum, dit ce qu'il pense de Rust, Go, Julia et TypeScript et relève des similitudes entre ces langages et Python