Rust 1.35.0 Release: Implémentations de traits fonctionnels et autres innovations

Je présente à votre attention une traduction de la publication sur la nouvelle version du langage de programmation préféré de tout le monde, Rust .


Présentation


L'équipe du langage de programmation Rust est heureuse d'annoncer une nouvelle version, 1.35.0. Rust est un langage de programmation qui permet à chacun de développer des logiciels fiables et rapides.


Si vous avez installé la version précédente de Rust à l'aide de rustup , obtenir la version actuelle ne sera pas difficile:


 $ rustup update stable 

Si vous n'avez toujours pas de rustup , vous pouvez l' obtenir à partir de la page correspondante sur notre site Web. Une revue détaillée de cette version est disponible sur GitHub.


Qu'est-ce qui est inclus dans la version stable?


Les principales innovations de cette version incluent l'implémentation des caractéristiques FnOnce, FnMut et Fn sur les Box<dyn FnOnce> , Box<dyn FnMut> et Box<dyn Fn> , respectivement.


Ainsi que les fonctions en ligne (fermetures) peuvent être converties en pointeurs de fonction non sécurisés. Macro dbg! introduit dans Rust 1.32.0 peut maintenant être appelé sans spécifier d'arguments.


De plus, cette version a introduit de nombreuses stabilisations de la bibliothèque standard. Ci-dessous sont les plus importants, mais une analyse détaillée de certains d'entre eux est disponible.


Traits Fn* implémentés sur Box<dyn Fn*>


Dans Rust 1.35.0, les FnOnce , FnMut et Fn FnMut implémentés respectivement dans Box<dyn FnOnce> , Box<dyn FnMut> et Box<dyn Fn> .


Dans le passé, si vous vouliez appeler une fonction encapsulée dans Box<T> , vous FnBox utiliser FnBox , car les objets Box<dyn FnOnce> et similaires Box<dyn FnOnce> pas les traits Fn* correspondants. Il a également empêché le transfert des fonctions encapsulées dans la Box<T> vers le code qui attendait l'implémentateur de traits Fn (il a été proposé de créer des fonctions en ligne temporaires).


Cela était dû à l'incapacité du compilateur à détecter de telles implémentations. Cette faille a été corrigée avec l'introduction de unsized_locals .


Cependant, vous pouvez maintenant utiliser les fonctions encapsulées dans la Box<T> même dans les endroits qui s'attendent à ce qu'un trait fonctionnel soit implémenté. Par exemple, le code ci-dessous se compile sans erreur:


 fn foo(x: Box<dyn Fn(u8) -> u8>) -> Vec<u8> { vec![1, 2, 3, 4].into_iter().map(x).collect() } 

Box<dyn FnOnce> peuvent être appelés sans Box<dyn FnOnce> bruit:


 fn foo(x: Box<dyn FnOnce()>) { x() } 

Conversion en pointeurs dangereux


Depuis l'époque de Rust 1.19.0, il est devenu possible de convertir des fonctions intégrées qui ne capturent pas l'environnement en pointeurs de fonction. Par exemple, vous pourriez écrire:


 fn twice(x: u8, f: fn(u8) -> u8) -> u8 { f(f(x)) } fn main() { assert_eq!(42, twice(0, |x| x + 21)); } 

Mais malheureusement, cette fonctionnalité n'a pas été étendue aux pointeurs de fonction dangereux. Cette version a introduit les modifications décrites ci-dessus:


 ///  ,   `unsafe fn`. unsafe fn call_unsafe_fn_ptr(f: unsafe fn()) { f() } fn main() { // :     //       //  unsafe { call_unsafe_fn_ptr(|| { dbg!(); }); } } 

Appelez dbg!() Sans argument


En raison de l'abondance d'appels println! en tant que débogueurs de ferme collective, la macro dbg! été introduite dans Rust 1.32.0 dbg! . Rappelons que cette macro vous permet de capturer rapidement le résultat d'une certaine expression avec le contexte:


 fn main() { let mut x = 0; if dbg!(x == 1) { x += 1; } dbg!(x); } 

Les lignes de code ci-dessus imprimeront sur le terminal le résultat de l'expression x == 1 et x respectivement:


 [src/main.rs:4] x == 1 = false [src/main.rs:8] x = 0 

Comme mentionné dans la section précédente, où une fonction d'ordre supérieur call_unsafe_fn_ptr peut être appelée, dbg!() également être appelé sans spécifier d'arguments. Cela peut être extrêmement utile pour découvrir des branches de programme sélectionnées:


 fn main() { let condition = true; if condition { dbg!(); // [src/main.rs:5] } } 

Stabilisation de la bibliothèque standard


Dans Rust 1.35.0, de nombreux composants de la bibliothèque standard ont été stabilisés. En plus de cela, certaines implémentations ont été introduites, que vous pouvez lire ici .


Copiez le signe d'un nombre à virgule flottante dans un autre nombre


Avec cette version, de nouvelles méthodes de copysign été ajoutées aux primitives à virgule flottante (plus précisément, f32 et f64 ):



Comme le nom des méthodes le suggère, vous pouvez les utiliser pour copier le signe d'un nombre sur un autre:


 fn main() { assert_eq!(3.5_f32.copysign(-0.42), -3.5); } 

Vérifier si la Range contient une valeur spécifique


Rust 1.35.0 a acquis quelques nouvelles méthodes sur les structures Range* :



En utilisant ces méthodes, vous pouvez facilement vérifier si une certaine valeur se trouve dans une plage. Par exemple, vous pouvez écrire:


 fn main() { if (0..=10).contains(&5) { println!("5    [0; 10]."); } } 

Traduire (carte) et fractionner RefCell emprunté


Avec l'avènement de Rust 1.35.0, vous pouvez traduire et diviser la valeur RefCell empruntée en un ensemble de valeurs empruntées en différents composants des données empruntées:



RefCell valeur RefCell via la fonction en ligne


Cette version présente la méthode replace_with pratique déclarée sur la structure RefCell :



Hacher un pointeur ou un lien vers


Cette version présente la fonction ptr::hash , qui prend un pointeur brut pour le hachage. L'utilisation de ptr::hash peut empêcher le hachage d'une valeur spécifiée ou référencée au lieu de l'adresse elle-même.


Option<&T> contenu de copie Option<&T>


Avec le début de Rust 1.0.0, les méthodes Option::cloned sur Option<&T> et Option<&mut T> ont permis de cloner le contenu s'il était présent ( Some(_) ). Cependant, le clonage peut parfois être une opération coûteuse et les méthodes opt.cloned() ne décrivent aucun indice.


Cette version a contribué:



La fonctionnalité de opt.copied() est la même que opt.cloned() . Cependant, la méthode décrite ci-dessus demande les conditions T: Copy , dont l'échec entraînera une erreur de compilation.


Changements Clippy


Clippy, un outil qui détecte les imperfections courantes pour améliorer la qualité du code, a acquis drop_bounds . Cela fonctionne lorsque la fonction généralisée demande la réalisation de la condition T: Drop :


 fn foo<T: Drop>(x: T) {} 

C'est souvent une erreur car les primitives n'implémentent pas Drop . De plus, T: Drop ne couvre pas les types comme String , qui n'ont pas un comportement destructeur, mais plutôt le résultat de types en ligne (comme Vec<u8> ).


Outre drop_bounds , cette version divise redundant_closure en redundant_closure et redundant_closure_for_method_calls .


Lisez la version détaillée de Clippy ici .


Changements dans le fret


Une description détaillée des modifications apportées au fret est disponible ici .


Membres 1.35.0


Beaucoup de gens se sont réunis pour créer Rust 1.35.0. Nous n'aurions pas pu faire cela sans vous tous, merci !


Du traducteur


Pour toute question sur la langue rouille, ils pourront vous aider dans le chat Telegram en russe ou dans un chat similaire pour les nouveaux arrivants .

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


All Articles