Version Rust 1.31 et Rust 2018

L'équipe de développement de Rust est heureuse d'annoncer la sortie d'une nouvelle version de Rust, 1.31.0, ainsi que "Rust 2018". Rust est un langage de programmation qui permet à chacun de créer des logiciels fiables et efficaces.


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.31.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.31.0 sont disponibles sur GitHub.


Ce qui est inclus dans la version stable 1.31.0


Rust 1.31 est sans doute la version la plus importante depuis Rust 1.0! La première itération de «Rust 2018» est incluse dans cette version, mais ce n'est pas la seule innovation! L'examen des améliorations sera long, voici donc la table des matières:


  • Rouille 2018
    • Temps de vie non lexicaux
    • Modifications du système des modules
  • Règles supplémentaires pour l'affichage des durées de vie
  • const fn
  • De nouveaux outils
  • Contrôles de qualité du code instrumental
  • La documentation
  • Groupes de travail thématiques
  • Nouveau site web
  • Stabilisation de la bibliothèque standard
  • Améliorations du fret
  • Développeurs de versions

Rouille 2018


Nous avons écrit sur Rust 2018 pour la première fois en mars , puis en juillet . Pour plus de détails sur les raisons pour lesquelles vous avez besoin de Rust 2018, reportez-vous à ces publications. Dans cette revue, il y a tellement de choses à nous dire, nous allons donc nous concentrer uniquement sur ce qu'est Rust 2018. Vous pouvez également lire à ce sujet dans un article sur Mozilla Hacks ( traduction ).


En bref, Rust 2018 est une opportunité d'intégrer tout le travail que nous avons accompli au cours des trois dernières années dans un ensemble cohérent. Rust 2018 est bien plus qu'un tas d'améliorations linguistiques. En plus d'eux, il comprend:


  • Toolkit (support dans IDE, rustfmt , Clippy)
  • La documentation
  • Groupes de travail thématiques
  • Nouveau site web

Plus loin, nous parlerons de tout cela plus en détail et d'autres innovations.


Créons un nouveau projet en utilisant Cargo:


 $ cargo new foo 

Voici le contenu de Cargo.toml :


 [package] name = "foo" version = "0.1.0" authors = ["Your Name <you@example.com>"] edition = "2018" [dependencies] 

Une nouvelle clé a été ajoutée à la section [package] : edition . Veuillez noter qu'il est installé en 2018 . Vous pouvez également l'installer en 2015 - cette valeur sera définie par défaut si la clé est manquante.


L'utilisation de Rust 2018 débloquera de nouvelles fonctionnalités qui ne sont pas autorisées dans Rust 2015.


Il est important de noter que chaque package peut être en mode 2015 ou 2018 et fonctionnera ensemble. Votre projet de l'édition 2018 peut utiliser les dépendances de l'édition 2015 et le projet de l'édition 2015 peut utiliser les dépendances de l'édition 2018. Cela garantit l'intégrité de l'écosystème et que toutes les nouvelles fonctionnalités seront facultatives, tout en conservant la compatibilité avec le code existant. En outre, lorsque vous décidez de porter le code de Rust 2015 sur Rust 2018, des modifications peuvent être apportées automatiquement via la cargo fix .


Vous pouvez vous demander: qu'en est-il des nouvelles fonctionnalités elles-mêmes? Premièrement, ils sont également ajoutés dans Rust 2015, s'ils sont compatibles avec les fonctionnalités de cette édition. Ainsi, la plupart de la langue reste la même partout. Vous pouvez consulter le manuel éditorial pour connaître la version minimale de rustc pour chaque nouvelle fonctionnalité et ses autres exigences. Cependant, il existe plusieurs grandes innovations qui doivent être mentionnées séparément: les durées de vie non lexicales et certains changements dans le système de modules.


Temps de vie non lexicaux


Si vous suivez Rust au cours des dernières années, vous pouvez parfois rencontrer le terme «NLL» ou «durées de vie non lexicales». C'est du jargon qui, en termes simples, signifie: l'emprunteur est devenu plus intelligent et accepte maintenant un code correct, qu'il a rejeté auparavant. Prenons un exemple:


 fn main() { let mut x = 5; let y = &x; let z = &mut x; } 

Rust utilisé pour lancer une erreur de compilation:


 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 | 4 | let y = &x; | - immutable borrow occurs here 5 | 6 | let z = &mut x; | ^ mutable borrow occurs here 7 | } | - immutable borrow ends here 

En effet, le domaine de vie des liens a été défini «lexicalement»; c'est-à-dire que l'emprunt de y était considéré comme actif jusqu'à ce que y sorte du champ à la fin du main , même si nous n'utilisons plus jamais y dans le champ. Tout va bien avec le code ci-dessus, mais l'analyseur de dépendances ne pouvait pas comprendre cela.


Maintenant, ce code se compile très bien.


Et si on utilisait y ? Par exemple, comme ceci:


 fn main() { let mut x = 5; let y = &x; let z = &mut x; println!("y: {}", y); } 

La rouille vous donnait cette erreur:


 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:18 | 4 | let y = &x; | - immutable borrow occurs here 5 | let z = &mut x; | ^ mutable borrow occurs here ... 8 | } | - immutable borrow ends here 

Dans Rust 2018, ce message d'erreur s'est amélioré:


 error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> src/main.rs:5:13 | 4 | let y = &x; | -- immutable borrow occurs here 5 | let z = &mut x; | ^^^^^^ mutable borrow occurs here 6 | 7 | println!("y: {}", y); | - borrow later used here 

Au lieu d'indiquer où y sort du domaine, il montre où se produisent les emprunts conflictuels. Cela simplifie considérablement les erreurs de débogage de ce type.


Dans Rust 1.31, il s'agit d'une amélioration exclusivement pour Rust 2018. Nous prévoyons de l'ajouter à Rust 2015 plus tard.


Modifications du système des modules


Le système de modules peut être difficile pour les personnes qui apprennent Rust pour la première fois. Bien sûr, il y a toujours quelque chose qui prend du temps à maîtriser. Mais la raison principale pour laquelle les modules sont si embarrassants pour beaucoup est que malgré les règles simples et cohérentes qui définissent le système des modules, les conséquences de leur utilisation peuvent sembler contradictoires, mystérieuses et contre nature.


Par conséquent, l'édition 2018 apporte quelques modifications au fonctionnement des chemins, simplifiant le système de modules et le rendant plus compréhensible.


Voici un bref résumé:


  • extern crate n'est plus requise presque partout ailleurs.
  • Vous pouvez importer des macros à l'aide de use , au lieu d'utiliser l'attribut #[macro_use] .
  • Les chemins absolus commencent par le nom du conteneur, où le mot clé crate fait référence au conteneur actuel.
  • foo.rs et le sous foo/ répertoire foo/ peuvent coexister; mod.rs n'est plus requis lors du placement de sous-modules dans un sous-répertoire.

Cela ressemble à un ensemble arbitraire de règles, mais en général, le modèle mental a maintenant été considérablement simplifié.


Il y a encore beaucoup de détails, veuillez vous référer au manuel éditorial pour tous les détails.


Règles supplémentaires pour l'affichage des durées de vie


Parlons de l'amélioration disponible dans les deux éditions: nous avons ajouté quelques règles d'inférence supplémentaires pour les blocs impl et les définitions de fonctions. Code comme celui-ci:


 impl<'a> Reader for BufReader<'a> { //   } 

peut maintenant être écrit comme ceci:


 impl Reader for BufReader<'_> { //   } 

Lifetime '_ montre toujours que BufReader prend comme paramètre, mais nous n'avons plus besoin de lui donner de nom.


Les durées de vie doivent encore être définies dans les structures. Cependant, nous n'avons plus besoin d'écrire autant de code passe-partout qu'auparavant:


 // Rust 2015 struct Ref<'a, T: 'a> { field: &'a T } // Rust 2018 struct Ref<'a, T> { field: &'a T } 

Dépendance : 'a sera affiché. Vous pouvez toujours le spécifier explicitement si vous le souhaitez. Nous envisageons d'autres possibilités de retrait dans de tels endroits pour l'avenir, mais jusqu'à présent, nous n'avons aucun plan concret.


const fn


Rust a plusieurs façons de déclarer une fonction: fn pour les fonctions ordinaires, unsafe fn dangereux pour les fonctions dangereuses et extern fn pour les fonctions externes. Cette version ajoute une nouvelle façon de déclarer une fonction: const fn . Il est utilisé comme ceci:


 const fn foo(x: i32) -> i32 { x + 1 } 

Une fonction constante peut être appelée comme une fonction normale, mais en plus, elle peut être utilisée dans n'importe quel contexte constant. Cependant, il sera exécuté au moment de la compilation et non pendant l'exécution du programme. Par exemple:


 const SIX: i32 = foo(5); 

La fonction foo s'exécutera au moment de la compilation et SIX sera défini sur 6 .


Les fonctions constantes ne peuvent pas faire tout ce que les fonctions normales peuvent faire: elles doivent avoir un résultat déterministe. Ceci est important pour des raisons de fiabilité. Dans la forme actuelle, les fonctions constantes peuvent effectuer un sous-ensemble minimal d'opérations. Voici quelques exemples de ce que vous pouvez y faire:


  • Utiliser des opérations d'arithmétique et de comparaison entières
  • Utilisez toutes les opérations logiques sauf && et ||
  • Concevoir des tableaux, des structures, des énumérations et des tuples
  • Appeler d'autres fonctions constantes
  • Accès par index dans des tableaux et des tranches
  • Accéder aux domaines des structures et des tuples
  • Utilisez des constantes (mais pas des valeurs statiques, ni même des références à celles-ci)
  • Utiliser les liens & et *
  • Types de transtypage sauf le pointeur brut transtypé en valeur entière

Nous allons étendre les capacités des fonctions constantes, mais l'ensemble ci-dessus est déjà suffisant pour utiliser const fn en pratique.


Voir le manuel pour plus de détails.


De nouveaux outils


L'édition 2018 marque le début d'un nouveau niveau de maturité pour l'écosystème d'outils Rust. Cargo, Rustdoc et Rustup sont les principaux outils depuis la version 1.0; Avec l'édition 2018, une nouvelle génération d'outils arrive que tout le monde peut désormais utiliser: Clippy, Rustfmt et le support IDE.


L'analyseur de code statique clippy est maintenant disponible dans Rust stable. Vous pouvez l'installer via le rustup component add clippy et l'exécuter avec la cargo clippy . Clippy a maintenant reçu la version 1.0 et a les mêmes garanties de stabilité pour les contrôles statiques que rustc. De nouveaux contrôles peuvent être ajoutés ou la fonctionnalité des anciens peut être étendue, mais les anciens ne peuvent pas être supprimés (ils peuvent uniquement être marqués comme obsolètes). Cela signifie que le code qui compile avec clippy continuera de compiler avec clippy (en supposant qu'aucune vérification n'est définie pour générer
erreur via deny ), mais peut générer de nouveaux avertissements.


Rustfmt est un outil de formatage de code dans Rust. Le formatage automatique du code vous fera gagner du temps, en plus, il rapprochera votre code du style officiel de Rust . Vous pouvez l'installer via le rustup component add rustfmt et utiliser la commande cargo fmt .


La version actuelle comprend Rustfmt 1.0. Désormais, nous garantissons la compatibilité descendante de Rustfmt: si vous formatez votre code aujourd'hui, le formatage ne changera pas à l'avenir (uniquement pour les paramètres par défaut). La compatibilité descendante signifie qu'il est désormais pratique d'exécuter Rustfmt sur votre CI (utilisez cargo fmt --check ). Essayez ceci avec «formatage lors de l'enregistrement» dans l'éditeur, et votre flux de travail sera révolutionné.


Le support IDE est l'une des fonctionnalités les plus demandées pour Rust. Il existe maintenant plusieurs solutions de haute qualité:



Le travail de support dans l'IDE n'est pas terminé. En particulier, la complétion de code dans les éditeurs basés sur RLS n'est pas à la hauteur. Cependant, si vous souhaitez principalement prendre en charge les types, la documentation et la «transition vers la définition», vous serez satisfait.


Contrôles de qualité du code instrumental (lints d'outils)


Dans Rust 1.30, nous avons stabilisé les "attributs instrumentaux" tels que #[rustfmt::skip] . Dans Rust 1.31, nous avons stabilisé quelque chose comme ceci: "tool lints" comme #[allow(clippy::bool_comparison)] . Cela vous permet de spécifier des espaces de noms pour les vérifications afin de clarifier les outils dont ils proviennent.


Si vous avez déjà utilisé des contrôles Clippy, vous pouvez migrer comme suit:


 //  #![cfg_attr(feature = "cargo-clippy", allow(bool_comparison))] //  #![allow(clippy::bool_comparison)] 

Vous n'avez plus besoin de cfg_attr ! Vous recevrez également des avertissements qui vous aideront à passer à l'utilisation du nouveau style.


La documentation


Cette année, Rustdoc a connu plusieurs améliorations et le livre entièrement réécrit, The Rust Programming Language, a été publié. Vous pouvez acheter une copie papier de No Starch Press !


Il s'appelait auparavant la «deuxième édition» du livre, mais depuis qu'il est devenu la première édition imprimée, cela a semé la confusion. Après tout, l'édition imprimée devrait être mise à jour périodiquement. En fin de compte, après de nombreuses discussions avec No Starch, il a été décidé de mettre à jour le livre sur le site Web avec chaque version, et No Starch reprendrait périodiquement les modifications et les imprimerait. Le livre se vend assez bien et recueille des fonds pour Black Girls Code .


Vous pouvez trouver la nouvelle version du livre ici .


Groupes de travail thématiques


Cette année, nous avons annoncé la création de quatre groupes de travail:


  • Services réseau
  • Applications en ligne de commande
  • Webassembly
  • Appareils embarqués

Les groupes ont travaillé très dur pour améliorer Rust dans chacun de ces domaines. Voici quelques réalisations:


  • Les services réseau ont repensé l'interface pour Futures, et en plus async / wait. Ces améliorations n'ont pas encore été publiées, mais nous en sommes déjà proches!
  • L'équipe CLI a travaillé sur les bibliothèques et la documentation pour améliorer les applications en ligne de commande.
  • WebAssembly a publié de nombreux outils de classe mondiale pour utiliser Rust avec wasm.
  • Pour les appareils embarqués, il est devenu possible de développer ARM sur une Rust stable!

Vous pouvez en savoir plus sur tout cela sur notre nouveau site!


Nouveau site web


La semaine dernière, nous avons annoncé une nouvelle version de notre site Web. Maintenant, c'est devenu la version officielle de rust-lang.org!


Pour le créer, il a fallu un an de travail à de nombreuses personnes. Bien qu'il reste encore beaucoup à faire avant son achèvement, nous sommes fiers du travail accompli.


Stabilisation de la bibliothèque standard


From nouvelles implémentations From ont été ajoutées:


  • u8 implémente désormais From<NonZeroU8> , de même pour les autres types numériques et leurs équivalents non NonZero
  • Option<&T> implémente From<&Option<T>> , de manière similaire à &mut

Les fonctions suivantes ont également été stabilisées:



Voir les notes de version pour plus de détails.


Améliorations du fret


Cargo chargera désormais les colis en parallèle à l'aide de HTTP / 2.


De plus, comme la extern crate désormais facultative, il serait frustrant d'écrire la extern crate foo as bar; pour renommer la dépendance. Par conséquent, vous pouvez le faire dans Cargo.toml cette façon:


 [dependencies] baz = { version = "0.1", package = "foo" } 

ou, de manière équivalente:


 [dependencies.baz] version = "0.1" package = "foo" 

Le paquet foo est maintenant disponible en tant que baz pour une utilisation dans votre code.


Voir les notes de version pour plus de détails.


Développeurs 1.31.0


Habituellement, à la fin de la revue, nous remercions les personnes qui ont contribué à la publication . Mais cette fois, contrairement au passé, cette liste ne couvre pas entièrement toutes les personnes qui ont aidé, ni toute la quantité de travail qui a été fait. Chaque version régulière est le résultat de six semaines de travail, mais cette version est l'aboutissement de trois années d'efforts, reflétées dans la myriade de référentiels créés par un grand nombre de personnes. Nous avons été ravis de travailler avec vous tous et nous sommes impatients de poursuivre le développement de Rust au cours des trois prochaines années.


De la part d'un traducteur: Je remercie tout particulièrement les membres de la communauté Rustycrate et personnellement @dashadee , ozkriff , humbug et mvlabat pour leur aide avec la traduction et la relecture.

Source: https://habr.com/ru/post/fr432640/


All Articles