Lors de la célébration du dixième anniversaire de la sortie du langage de programmation Rust 1.0 (le projet Rust a été fondé en 2006, la version 0.1 a été formée en 2012, et la première version stable a été présentée en 2015), le lancement de Rust 1.87 a été publié. Le langage est axé sur la gestion sécurisée de la mémoire et offre des moyens d'atteindre un haut degré de parallélisme, tout en évitant l'utilisation d'un ramasse-miettes et d'un runtime (le runtime se limite à l'initialisation de base et à l'accompagnement de la bibliothèque standard).
Les méthodes de gestion de la mémoire en Rust éliminent les erreurs lors de la manipulation des pointeurs et protègent contre les problèmes liés à la gestion bas niveau de la mémoire, tels que l'accès à une zone mémoire après sa libération, la déréférence de pointeurs nuls, le dépassement de tampon, etc. Pour faciliter la diffusion des bibliothèques, assurer la compilation et gérer les dépendances, un gestionnaire de paquets nommé Cargo est en développement. Un dépôt pour le déploiement des bibliothèques, crates.io, est également supporté.
La sécurité de la mémoire dans Rust est assurée au moment de la compilation grâce à la vérification des références, au suivi de la propriété des objets, à la prise en compte de la durée de vie des objets (portée) et à l'évaluation de l'accès mémoire pendant l'exécution du code. Rust offre également des outils pour se protéger contre les débordements d'entiers, exige l'initialisation obligatoire des valeurs des variables avant leur utilisation, gère mieux les erreurs dans la bibliothèque standard, applique le concept d'immuabilité (immutable) pour les références et les variables par défaut, et propose une forte typage statique pour minimiser les erreurs logiques.
Les principales nouveautés :
- La bibliothèque standard a été mise à jour pour ajouter le support des canaux anonymes (anonymous pipe). Pour créer des canaux anonymes, la méthode std::io::pipe() a été proposée, qui peut être utilisée avec std::process::Command pour gérer les flux d'entrée et de sortie standard, ainsi que pour combiner les flux stdout et stderr. use std::process::Command; use std::io::Read; let (mut recv, send) = std::io::pipe()?; let mut command = Command::new("path/to/bin") // combinaison de stdout et stderr dans un seul canal .stdout(send.try_clone()?) .stderr(send) .spawn()?; let mut output = Vec::new(); recv.read_to_end(&mut output)?; assert!(command.wait()?.success());
- L'appel depuis du code sûr de la plupart des fonctions intégrées dans le compilateur (Intrinsics) std::arch est désormais autorisé. Le changement s'applique aux fonctions intégrées std::arch qui étaient marquées comme unsafe uniquement en raison de leur liaison à des fonctionnalités spécifiques, lorsque cette fonctionnalité est activée. Par exemple, _mm256_add_epi32 peut être appelé à partir de code sûr si l'application utilise ‘#[target_feature(enable = "avx2")]’.
- Il est désormais autorisé d'effectuer des transitions entre des blocs «asm!» contenant du code assembleur et des blocs contenant du code Rust, ce qui simplifie le développement de code bas niveau, par exemple, pour mettre en œuvre des optimisations dans le noyau ou organiser des interactions avec le matériel. Le point de transition pour l'instruction assembleur «jmp» est spécifié dans le macro «asm!» à l'aide du nouvel opérande «label», qui contient une expression de bloc avec du code en Rust. unsafe { asm!( «jmp {}», label { println!("Jumped from asm!"); } ); }
- Il est désormais possible de spécifier précisément les types génériques capturés et la durée de vie dans les définitions de traits en utilisant les types de retour impl Trait. trait Foo { fn method(&'a self) -> impl Sized; type Implicit1: Sized; fn method_desugared(&'a self) -> Self::Implicit1; fn precise(&'a self) -> impl Sized + use; type Implicit2: Sized; fn precise_desugared(&'a self) -> Self::Implicit2; }
- Une nouvelle série d'API a été stabilisée dans la catégorie des API stables, notamment des méthodes et des implémentations de traits stabilisées :
- Vec::extract_if
- vec::ExtractIf
- LinkedList::extract_if
- linked_list::ExtractIf
- ::split_off
- ::split_off_mut
- ::split_off_first
- ::split_off_first_mut
- ::split_off_last
- ::split_off_last_mut
- String::extend_from_within
- os_str::Display
- OsString::display
- OsStr::display
- io::pipe
- io::PipeReader
- io::PipeWriter
- impl From for OwnedHandle
- impl From for OwnedHandle
- impl From for Stdio
- impl From for Stdio
- impl From for OwnedFd
- impl From for OwnedFd
- Box<MaybeUninit>::write
- impl TryFrom<Vec> for String
- ::offset_from_unsigned
- ::byte_offset_from_unsigned
- ::offset_from_unsigned
- ::byte_offset_from_unsigned
- NonNull::offset_from_unsigned
- NonNull::byte_offset_from_unsigned
- ::cast_signed
- NonZero::::cast_signed.
- ::cast_unsigned.
- NonZero::::cast_unsigned.
- ::is_multiple_of
- ::unbounded_shl
- ::unbounded_shr
- ::unbounded_shl
- ::unbounded_shr
- ::midpoint
- ::from_utf8
- ::from_utf8_mut
- ::from_utf8_unchecked
- ::from_utf8_unchecked_mut
- L'attribut «const» est appliqué dans les fonctions :
- core::str::from_utf8_mut
- ::copy_from_slice
- SocketAddr::set_ip
- SocketAddr::set_port,
- SocketAddrV4::set_ip
- SocketAddrV4::set_port,
- SocketAddrV6::set_ip
- SocketAddrV6::set_port
- SocketAddrV6::set_flowinfo
- SocketAddrV6::set_scope_id
- char::is_digit
- char::is_whitespace
- <N::as_flattened
- <N::as_flattened_mut
- String::into_bytes
- String::as_str
- String::capacity
- String::as_bytes
- String::len
- String::is_empty
- String::as_mut_str
- String::as_mut_vec
- Vec::as_ptr
- Vec::as_slice
- Vec::capacity
- Vec::len
- Vec::is_empty
- Vec::as_mut_slice
- Vec::as_mut_ptr
- Le deuxième niveau de support pour la plateforme cible i586-pc-windows-msvc a été supprimé. Il est recommandé d'utiliser la plateforme i686-pc-windows-msvc, qui supporte les instructions SSE2. La plateforme i586-pc-windows-msvc est devenue obsolète, car la prise en charge de SSE2 est nécessaire pour Windows 10, et les versions antérieures de Windows ne sont pas prises en charge par Rust.
Source : opennet.ru
