L'équipe de développement de Rust est heureuse d'annoncer la sortie d'une nouvelle version de Rust: 1.30.0. Rust est un langage de programmation système destiné à la sécurité, la vitesse et l'exécution de code parallèle.
Si vous avez une version précédente de Rust installée à l'aide de rustup
, alors pour mettre à niveau Rust vers la version 1.30.0, il vous suffit de faire:
$ rustup update stable
Si vous n'avez pas encore installé rustup
, vous pouvez l' installer à partir de la page correspondante de notre site Web. Des notes de version détaillées pour Rust 1.30.0 sont disponibles sur GitHub.
Ce qui est inclus dans la version stable 1.30.0
Rust 1.30 est une version exceptionnelle avec un certain nombre d'innovations importantes. Mais lundi, le blog officiel sera publié une demande de vérification de la version bêta de Rust 1.31, qui sera la première version de "Rust 2018". Vous trouverez plus d'informations à ce sujet dans notre publication précédente «What is Rust 2018» .
Macros procédurales
De retour dans Rust 1.15, nous avons ajouté la possibilité de définir des "macros de dérivation personnalisées". Par exemple, en utilisant serde_derive
, vous pouvez déclarer:
#[derive(Serialize, Deserialize, Debug)] struct Pet { name: String, }
Et convertissez Pet
en JSON et revenez à la structure en utilisant serde_json
. Ceci est possible grâce à l'inférence automatique des Deserialize
Serialize
et Deserialize
aide de macros procédurales dans serde_derive
.
Rust 1.30 étend les fonctionnalités des macros procédurales en ajoutant la possibilité de définir deux autres types de macros: «macros procédurales attributaires» et «macros procédurales fonctionnelles».
Les macros d'attributs sont similaires aux macros dérivées pour la sortie automatique, mais au lieu de générer du code uniquement pour l'attribut #[derive]
, elles permettent aux utilisateurs de créer leurs propres nouveaux attributs. Cela les rend plus flexibles: les macros dérivées ne fonctionnent que pour les structures et les énumérations, mais les attributs peuvent être appliqués à d'autres objets, tels que des fonctions. Par exemple, les macros d'attributs vous permettront d'effectuer les opérations suivantes lors de l'utilisation d'un framework Web:
#[route(GET, "/")] fn index() {
Cet attribut #[route]
sera défini dans le cadre lui-même comme une macro procédurale. Sa signature ressemblera à ceci:
#[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
Ici, nous avons deux paramètres d'entrée de type TokenStream
: le premier est pour le contenu de l'attribut lui-même, c'est-à-dire, ce sont les paramètres GET, "/"
. Le second est le corps de l'objet auquel l'attribut est appliqué. Dans notre cas, il s'agit de fn index() {}
et du reste du corps de la fonction.
Les macros fonctionnelles définissent des macros dont l'utilisation ressemble à un appel de fonction. Par exemple, la sql!
:
let sql = sql!(SELECT * FROM posts WHERE id=1);
Cette macro en elle-même analysera les expressions SQL et vérifiera leur exactitude syntaxique. Une macro similaire doit être déclarée comme suit:
#[proc_macro] pub fn sql(input: TokenStream) -> TokenStream {
Ceci est similaire à la signature de la macro dérivée: nous obtenons les jetons qui sont à l'intérieur des crochets et retournons le code généré par eux.
Macros et use
Vous pouvez maintenant importer des macros dans la portée à l'aide du mot clé use . Par exemple, pour utiliser la macro serde-json
package serde-json
, l'entrée était:
#[macro_use] extern crate serde_json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
Et maintenant vous devrez écrire:
extern crate serde_json; use serde_json::json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
Ici, la macro est importée ainsi que d'autres éléments, il n'est donc pas nécessaire d'utiliser l'annotation macro_use
.
Enfin, le package proc_macro est stabilisé , ce qui fournit l'API nécessaire à l'écriture des macros procédurales. Il a également considérablement amélioré l'API de gestion des erreurs et des packages tels que syn
et quote
utilisent déjà. Par exemple, plus tôt:
#[derive(Serialize)] struct Demo { ok: String, bad: std::thread::Thread, }
conduit à cette erreur:
error[E0277]: the trait bound `std::thread::Thread: _IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not satisfied --> src/main.rs:3:10 | 3 | #[derive(Serialize)] | ^^^^^^^^^ the trait `_IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not implemented for `std::thread::Thread`
Maintenant, il sera publié:
error[E0277]: the trait bound `std::thread::Thread: serde::Serialize` is not satisfied --> src/main.rs:7:5 | 7 | bad: std::thread::Thread, | ^^^ the trait `serde::Serialize` is not implemented for `std::thread::Thread`
Amélioration du système de modules
Le système de modules a longtemps été un point sensible pour les débutants à Rust; certaines de ses règles n'étaient pas pratiques dans la pratique. Ces changements sont la première étape que nous prenons pour simplifier le système de modules.
En plus du changement ci-dessus pour les macros, il y a deux nouvelles améliorations à use
. Tout d'abord, des packages externes sont désormais ajoutés au prélude , à savoir:
Le hic, c'est que l'ancien style n'était pas toujours nécessaire en raison des caractéristiques du système de modules Rust:
extern crate serde_json; fn main() { // ; , `serde_json` // let json = serde_json::from_str("..."); } mod foo { fn bar() { // ; `foo`, `serde_json` // let json = serde_json::from_str("..."); } // - `use` use serde_json; fn baz() { // - `::serde_json`, // , let json = ::serde_json::from_str("..."); } }
C'était ennuyeux d'obtenir du code cassé en déplaçant simplement la fonction vers un sous-module. Maintenant, la première partie du chemin sera vérifiée, et si elle correspond à une extern crate
, elle sera utilisée quelle que soit la position de l'appel dans la hiérarchie du module.
Enfin, l' utilisation a commencé à prendre en charge l'importation d'éléments dans la portée actuelle avec des chemins qui commencent sur la caisse :
mod foo { pub fn bar() {
Le mot clé crate
au début du chemin indique que le chemin commencera à la racine du paquet. Auparavant, les chemins indiqués dans la ligne d'importation d'importation étaient toujours spécifiés par rapport à la racine du package, mais les chemins dans le reste du code qui se réfèrent directement aux éléments étaient spécifiés par rapport au module actuel, ce qui entraînait un comportement de chemin conflictuel:
mod foo { pub fn bar() {
Dès que le nouveau style sera largement utilisé, nous espérons que les chemins absolus seront plus clairs sans avoir à utiliser le préfixe laid ::
.
L'ensemble de ces modifications simplifie la compréhension de la résolution des chemins. Partout où vous voyez le chemin a::b::c
, à l'exception de l'instruction use
, vous pouvez demander:
- Est un nom de package? Ensuite, vous devez rechercher
b::c
intérieur. - Est-ce
a
crate
mots a
clés? Ensuite, vous devez rechercher b::c
à la racine du package actuel. - Sinon, vous devez rechercher
a::b::c
partir de la position actuelle dans la hiérarchie du module.
L'ancien comportement des chemins use
, toujours en commençant à la racine du package, est toujours applicable. Mais avec une transition unique vers un nouveau style, ces règles seront appliquées aux chemins partout de manière uniforme, et vous devrez vous soucier beaucoup moins des importations lors du déplacement de code.
Identifiants bruts
Vous pouvez désormais utiliser des mots clés comme identifiants à l'aide de la nouvelle syntaxe suivante:
Jusqu'à présent, il n'y a pas beaucoup de cas où cela vous est utile. Mais un jour, vous essaierez d'utiliser le package pour Rust 2015 dans un projet pour Rust 2018 ou vice versa, leur ensemble de mots clés sera différent. Nous en parlerons plus dans la prochaine annonce de Rust 2018.
Applications sans bibliothèque standard
De retour dans Rust 1.6, nous avons annoncé la stabilisation de "no_std" et de libcore pour créer des projets sans bibliothèque standard. Cependant, avec une précision: il était possible de créer uniquement des bibliothèques, mais pas des applications.
Dans Rust 1.30, vous pouvez utiliser l'attribut #[panic_handler]
pour implémenter indépendamment la panique. Cela signifie que vous pouvez maintenant créer des applications, pas seulement des bibliothèques qui n'utilisent pas la bibliothèque standard.
Autre
Une dernière chose: dans les macros, vous pouvez désormais mapper des modificateurs de portée , tels que pub
, à l'aide du qualificateur vis
. De plus, les "attributs d'outils", tels que #[rustfmt::skip]
, sont désormais stabilisés . Vrai pour une utilisation avec des outils d'analyse statique , comme #[allow(clippy::something)]
, ils ne sont pas encore stables.
Voir les notes de version pour plus de détails.
Stabilisation de la bibliothèque standard
Les API suivantes ont été stabilisées dans cette version:
Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
Iterator::find_map
De plus, la bibliothèque standard possède depuis longtemps des fonctions pour supprimer les espaces sur un côté du texte, comme trim_left
. Cependant, pour les langues RTL, la signification de «droite» et «gauche» ici crée de la confusion. Par conséquent, nous introduisons de nouveaux noms pour ces fonctions:
trim_left
-> trim_start
trim_right
-> trim_end
trim_left_matches
-> trim_start_matches
trim_right_matches
-> trim_end_matches
Nous prévoyons de déclarer les anciens noms obsolètes (mais pas de les supprimer, bien sûr) dans Rust 1.33.
Voir les notes de version pour plus de détails.
Améliorations du fret
La plus grande amélioration de Cargo dans cette version est que nous avons maintenant une barre de progression!

Voir les notes de version pour plus de détails.
Développeurs 1.30.0
Beaucoup de gens ont créé ensemble Rust 1.30. Nous n'aurions pas pu terminer le travail sans chacun de vous. Je vous remercie!
De la part d'un traducteur: J'exprime une gratitude particulière aux membres de la communauté Rustycrate et personnellement à vitvakatu et Virtuos86 pour leur aide dans la traduction et la relecture.