Rust est mis à jour régulièrement, souvent tous les mois. Ainsi, si vous avez déjà installé une version antérieure de Rust via rustup, vous pouvez accéder à la dernière version en tapant la commande suivante :
Code : | Sélectionner tout |
$ rustup update stable
Implémentation MVP des const generics
Avec l'implémentation MVP des const generics, un outil est ajouté pour les concepteurs de bibliothèques afin de développer des API sûres au moment de la compilation. Fonction très attendue, les const generics sont des arguments génériques qui portent sur des valeurs constantes, plutôt que sur des types ou des durées de vie. Cela permet aux types d'être paramétrés par des entiers, par exemple. L'équipe prévoit d'introduire progressivement les const generics, de sorte que les seuls types qui peuvent être utilisés comme type d'un argument const generic sont actuellement les types d'entiers, y compris size, usize, char et bool.
En effet, avant cette version, Rust vous permettait de paramétrer vos types sur des durées de vie ou des types. Par exemple, si vous vouliez avoir une structure qui soit générique sur le type d'élément d'un tableau, vous écririez ce qui suit :
Code Rust : | Sélectionner tout |
1 2 3 4 5 | struct FixedArray<T> { // ^^^ Type generic definition list: [T; 32] // ^ Where we're using it. } |
Si vous utilisez ensuite FixedArray<u8>, le compilateur créera une version monomorphe de FixedArray qui ressemblera à ceci :
Code Rust : | Sélectionner tout |
1 2 3 | struct FixedArray<u8> { list: [u8; 32] } |
Selon l'équipe de Rust, il s'agit d'une fonctionnalité puissante qui vous permet d'écrire du code réutilisable sans frais d'exécution. Cependant, jusqu'à cette version, il n'était pas possible d'être facilement générique sur les valeurs de ces types. Cela était particulièrement vrai pour les tableaux qui incluent leur longueur dans leur définition de type ([T ; N]), sur lesquels il était auparavant impossible d'être générique. Maintenant, avec la version 1.51.0, vous pouvez écrire du code qui est générique sur les valeurs de n'importe quel type integer, bool, ou char (l'utilisation de valeurs struct ou enum est toujours instable).
Ce changement vous permet maintenant d'avoir votre propre structure de tableau qui est générique sur son type et sa longueur. Examinons un exemple de définition et la façon dont elle peut être utilisée.
Code Rust : | Sélectionner tout |
1 2 3 4 5 | struct Array<T, const LENGTH: usize> { // ^^^^^^^^^^^^^^^^^^^ Const generic definition. list: [T; LENGTH] // ^^^^^^ We use it here. } |
Maintenant si vous utilisez Array<u8, 32>, le compilateur fera une version monomorphe de Array qui ressemble à :
Code Rust : | Sélectionner tout |
1 2 3 | struct Array<u8, 32> { list: [u8; 32] } |
Stabilisation de array::IntoIter
Avec les const generics, une nouvelle API a été stabilisée qui les utilise, std::array::IntoIter. Intolter permet aux développeurs de créer un itérateur par valeur sur n'importe quel tableau. Auparavant, il n'y avait pas de moyen pratique d'itérer sur les valeurs possédées d'un tableau, seulement sur les références à celles-ci.
Code Rust : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | fn main() { let array = [1, 2, 3, 4, 5]; // Previously for item in array.iter().copied() { println!("{}", item); } // Now for item in std::array::IntoIter::new(array) { println!("{}", item); } } |
Notez que ceci est ajouté en tant que méthode séparée au lieu de .into_iter() sur les tableaux, car cela introduit actuellement un certain nombre de ruptures. Pour le moment, .into_iter() fait référence à l'itérateur de tranche par référence. L'équipe explore les moyens de rendre cela plus ergonomique à l'avenir.
Resolver : nouvelle fonctionnalité de Cargo
D'après l'équipe, la gestion des dépendances est un problème difficile, et l'une des parties les plus difficiles est de choisir la version d'une dépendance à utiliser lorsqu'elle est dépendante de deux paquets différents. Cela ne comprend pas seulement son numéro de version, mais aussi les fonctionnalités qui sont ou ne sont pas activées pour le paquet. Le comportement par défaut de Cargo consiste à fusionner les fonctionnalités d'un seul paquet lorsqu'il est mentionné plusieurs fois dans le graphe des dépendances.
Par exemple, lorsque que vous avez une dépendance appelée foo avec les fonctionnalités A et B, qui est utilisée par les paquets bar et baz, mais bar dépend de foo+A et baz dépend de foo+B. Cargo fusionnera ces deux fonctionnalités et compilera foo comme foo+AB. L'avantage est que vous n'avez à compiler foo qu'une seule fois, et qu'il peut ensuite être réutilisé pour bar et baz. Cependant, cela comporte aussi un inconvénient. Que faire si une fonctionnalité activée dans une dépendance de construction n'est pas compatible avec la cible pour laquelle vous construisez ?
Un exemple commun de ceci dans l'écosystème est la fonctionnalité optionnelle std incluse dans beaucoup de crates #![no_std], qui permet aux crates de fournir des fonctionnalités supplémentaires lorsque std est disponible. Imaginez maintenant que vous voulez utiliser la version #![no_std] de foo dans votre binaire #![no_std], et utiliser foo au moment de la construction dans votre build.rs. Si votre dépendance au moment de la construction dépend de foo+std, votre binaire dépend maintenant aussi de foo+std, ce qui signifie qu'il ne compilera plus, car std n'est pas disponible pour votre plateforme cible.
C'est un problème de longue date dans Cargo, et avec cette version il y a une nouvelle option resolver dans votre Cargo.toml, où vous pouvez définir resolver="2" pour dire à Cargo d'essayer une nouvelle approche pour résoudre les fonctionnalités. Vous pouvez consulter la RFC 2957 pour une description détaillée du comportement, qui peut être résumée comme suit.
- dépendances de développement : lorsqu'un paquet est partagé en tant que dépendance normale et dépendance de développement, les fonctionnalités de la dépendance de développement ne sont activées que si la construction actuelle inclut des dépendances de développement ;
- dépendances hôte : lorsqu'un paquet est partagé en tant que dépendance normale et en tant que dépendance de construction ou proc-macro, les fonctionnalités de la dépendance normale sont conservées indépendamment de la dépendance de construction ou proc-macro ;
- dépendances de cible : lorsqu'un paquet apparaît plusieurs fois dans le graphe de construction, et que l'une de ces instances est une dépendance spécifique à la cible, les fonctionnalités de la dépendance spécifique à la cible ne sont activées que si la cible est en cours de construction.
Par ailleurs, l'équipe informe que, bien que cela puisse entraîner la compilation de certains crates plus d'une fois, cela devrait fournir une expérience de développement beaucoup plus intuitive lors de l'utilisation de fonctionnalités avec Cargo. Si vous souhaitez en savoir plus, vous pouvez également lire la section "Feature Resolver" dans le Cargo Book pour plus d'informations.
Code : | Sélectionner tout |
1 2 3 4 5 | [package] resolver = "2" # Or if you're using a workspace [workspace] resolver = "2" |
Selon l'équipe, cette version marque l'une des plus grandes améliorations depuis longtemps pour Rust sur macOS. Les informations de débogage font correspondre le code binaire à votre code source, afin que le programme puisse vous donner plus d'informations sur ce qui s'est mal passé lors de l'exécution. Sous macOS, les informations de débogage étaient auparavant rassemblées dans un seul dossier .dSYM à l'aide d'un outil appelé dsymutil, ce qui peut prendre un certain temps et occuper pas mal d'espace disque.
La collecte de toutes les informations de débogage dans ce répertoire permet de les retrouver au moment de l'exécution, en particulier si le binaire est déplacé. Cependant, il y a un inconvénient : même si vous apportez une petite modification à votre programme, dsymutil devra parcourir tout le binaire final pour produire le dossier .dSYM final. Cela peut parfois ajouter beaucoup au temps de construction, surtout pour les grands projets, car toutes les dépendances sont toujours récupérées, mais c'est une étape nécessaire, car sans elle, la bibliothèque standard de Rust ne savait pas comment charger les informations de débogage sur macOS.
Récemment, les backtraces Rust sont passés à l'utilisation d'un backend différent qui supporte le chargement des informations de débogage sans avoir besoin d'exécuter dsymutil, et l'équipe a stabilisé le support pour sauter l'exécution de dsymutil. Selon elle, cela peut accélérer de manière significative les constructions qui incluent des debuginfo et réduire de manière significative l'espace disque utilisé.
API stabilisées
Au total, cette version a vu la stabilisation de 18 nouvelles méthodes pour divers types comme slice et Peekable. Un ajout notable est la stabilisation de ptr::addr_of! et ptr::addr_of_mut!, qui vous permettent de créer des pointeurs bruts vers des champs non alignés. Auparavant, cela n'était pas possible parce que Rust exige que &/&mut soit aligné et pointe vers des données initialisées, et que &addr en tant que *const _ provoquerait alors un comportement non défini puisque &addr doit être aligné. Ces deux macros vous permettent maintenant de créer en toute sécurité des pointeurs non alignés. Les méthodes suivantes ont été stabilisées.
- Arc::decrement_strong_count ;
- Arc::increment_strong_count ;
- Once::call_once_force ;
- Peekable::next_if_eq ;
- Peekable::next_if ;
- Seek::stream_position ;
- array::IntoIter ;
- panic::panic_any ;
- ptr::addr_of! ;
- ptr::addr_of_mut! ;
- slice::fill_with ;
- slice::split_inclusive_mut ;
- slice::split_inclusive ;
- slice::strip_prefix ;
- slice::strip_suffix ;
- str::split_inclusive ;
- sync::OnceState ;
- task::Wake.
Source : Rust 1.51.0
Et vous ?
Que pensez-vous des nouveautés de Rust 1.51 ?
Voir aussi
Rust 1.50.0 est disponible et s'accompagne de l'indexation de tableau générique Const, ainsi que des affectations sécurisées aux champs d'union ManuallyDrop<T>
Évolution de l'écosystème Rust en 2020 : Rust continue de faire des percées en tant que langage utilisé pour la production, les développeurs réclament une plus grande interopérabilité avec C++
Microsoft, Google, AWS, Huawei et Mozilla s'associent pour créer la Fondation Rust, une organisation à but non lucratif chargée de gérer le langage de programmation
Rust 1.49.0 est disponible avec l'amélioration des supports de Linux ARM 64 bits, macOS et Windows ARM 64 bits