Rust 1.30 Release

Das Rust-Entwicklungsteam freut sich, die Veröffentlichung einer neuen Version von Rust bekannt zu geben: 1.30.0. Rust ist eine Systemprogrammiersprache, die auf Sicherheit, Geschwindigkeit und parallele Codeausführung abzielt.


Wenn Sie eine frühere Version von Rust mit rustup installiert rustup , müssen Sie nur Folgendes tun, um Rust auf Version 1.30.0 zu aktualisieren:


 $ rustup update stable 

Wenn Sie rustup noch nicht installiert rustup , können Sie es von der entsprechenden Seite unserer Website installieren . Detaillierte Versionshinweise für Rust 1.30.0 sind auf GitHub verfügbar.


Was ist in der stabilen Version 1.30.0 enthalten


Rust 1.30 ist eine herausragende Veröffentlichung mit einer Reihe wichtiger Innovationen. Am Montag wird im offiziellen Blog eine Anfrage zur Überprüfung der Beta-Version von Rust 1.31 veröffentlicht, der ersten Veröffentlichung von "Rust 2018". Weitere Informationen hierzu finden Sie in unserer vorherigen Veröffentlichung „What is Rust 2018“ .


Prozedurale Makros


Zurück in Rust 1.15 haben wir die Möglichkeit hinzugefügt, "benutzerdefinierte Ableitungsmakros" zu definieren. Mit serde_derive können Sie beispielsweise serde_derive deklarieren:


 #[derive(Serialize, Deserialize, Debug)] struct Pet { name: String, } 

Und konvertieren Sie Pet mit serde_json in JSON und zurück in die Struktur. Dies ist dank der automatischen Inferenz von Serialize und Deserialize mithilfe von prozeduralen Makros in serde_derive .


Rust 1.30 erweitert die Funktionalität von prozeduralen Makros um die Möglichkeit, zwei weitere Arten von Makros zu definieren: "Attribut prozedurale Makros" und "funktionale prozedurale Makros".


Attributmakros ähneln dem Ableiten von Makros für die automatische Ausgabe, aber anstatt Code nur für das Attribut #[derive] generieren, können Benutzer ihre eigenen neuen Attribute erstellen. Dies macht sie flexibler: Ableiten von Makros funktioniert nur für Strukturen und Aufzählungen, Attribute können jedoch auch auf andere Objekte wie Funktionen angewendet werden. Mit Attributmakros können Sie beispielsweise Folgendes verwenden, wenn Sie ein Webframework verwenden:


 #[route(GET, "/")] fn index() { 

Dieses Attribut #[route] wird im Framework selbst als prozedurales Makro definiert. Seine Unterschrift wird so aussehen:


 #[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream { 

Hier haben wir zwei Eingabeparameter vom Typ TokenStream : Der erste TokenStream sich auf den Inhalt des Attributs selbst, TokenStream die Parameter GET, "/" . Der zweite ist der Hauptteil des Objekts, auf das das Attribut angewendet wird. In unserem Fall ist dies fn index() {} und der Rest des Funktionskörpers.


Funktionsmakros definieren Makros, deren Verwendung wie ein Funktionsaufruf aussieht. Zum Beispiel das sql! ::


 let sql = sql!(SELECT * FROM posts WHERE id=1); 

Dieses Makro in sich selbst analysiert SQL-Ausdrücke und überprüft sie auf syntaktische Korrektheit. Ein ähnliches Makro sollte wie folgt deklariert werden:


 #[proc_macro] pub fn sql(input: TokenStream) -> TokenStream { 

Dies ähnelt der Signatur des Ableitungsmakros: Wir erhalten die Token in den Klammern und geben den von ihnen generierten Code zurück.


Makros und use


Jetzt können Sie Makros mit dem Schlüsselwort use in den Bereich importieren . Um beispielsweise das json Makro aus dem serde-json Paket zu verwenden, serde-json der Eintrag früher:


 #[macro_use] extern crate serde_json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] }); 

Und jetzt müssen Sie schreiben:


 extern crate serde_json; use serde_json::json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] }); 

Hier werden das Makro sowie andere Elemente importiert, sodass die Annotation macro_use nicht verwendet werden macro_use .


Schließlich wird das Paket proc_macro stabilisiert , das die zum Schreiben von prozeduralen Makros erforderliche API bereitstellt. Außerdem wurde die Fehlerbehandlungs-API erheblich verbessert, und Pakete wie syn und quote verwenden sie bereits. Zum Beispiel früher:


 #[derive(Serialize)] struct Demo { ok: String, bad: std::thread::Thread, } 

führte zu diesem Fehler:


 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` 

Jetzt wird es ausgestellt:


 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` 

Verbesserung des Modulsystems


Das Modulsystem ist seit langem ein wunder Punkt für Anfänger in Rust; Einige seiner Regeln waren in der Praxis unpraktisch. Diese Änderungen sind der erste Schritt zur Vereinfachung des Modulsystems.


Zusätzlich zu der obigen Änderung für Makros gibt es zwei neue Verbesserungen für die use . Zunächst werden jetzt externe Pakete zum Vorspiel hinzugefügt , d. H.


 //  let json = ::serde_json::from_str("..."); //  let json = serde_json::from_str("..."); 

Der Haken ist, dass der alte Stil aufgrund der Merkmale des Rust-Modulsystems nicht immer benötigt wurde:


 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("..."); } } 

Es war ärgerlich, fehlerhaften Code zu erhalten, indem die Funktion einfach in ein Submodul verschoben wurde. Jetzt wird der erste Teil des Pfades überprüft, und wenn er einer extern crate , wird er unabhängig von der Position des Aufrufs in der Modulhierarchie verwendet.


Schließlich begann die Verwendung, den Import von Elementen in den aktuellen Bereich mit Pfaden zu unterstützen, die auf der Kiste beginnen :


 mod foo { pub fn bar() { // ... } } //  use ::foo::bar; //  use foo::bar; //  use crate::foo::bar; 

Das Schlüsselwort crate am Anfang des Pfads gibt an, dass der Pfad am Stammverzeichnis des Pakets beginnt. Bisher wurden die in der Importzeile für die use angegebenen Pfade immer relativ zum Stammverzeichnis des Pakets angegeben. Die Pfade im Rest des Codes, die direkt auf die Elemente verweisen, wurden jedoch relativ zum aktuellen Modul angegeben, was zu einem inkonsistenten Verhalten der Pfade führte:


 mod foo { pub fn bar() { // ... } } mod baz { pub fn qux() { //  ::foo::bar(); //  ,    `use`: // foo::bar(); //  crate::foo::bar(); } } 

Sobald der neue Stil weit verbreitet ist, werden hoffentlich die absoluten Pfade klarer, ohne dass das hässliche Präfix :: .


Alle diese Änderungen zusammen vereinfachen das Verständnis, wie Pfade aufgelöst werden. Wo immer Sie den Pfad a::b::c , mit Ausnahme der use Anweisung, können Sie fragen:


  • Ist a Paketname? Dann müssen Sie darin nach b::c suchen.
  • Ist a Keyword- crate ? Dann müssen Sie im Stammverzeichnis des aktuellen Pakets nach b::c suchen.
  • Andernfalls müssen Sie an der aktuellen Position in der Modulhierarchie nach a::b::c suchen.

Das alte Verhalten der verwendeten Pfade, das immer am Stammverzeichnis des Pakets beginnt, ist weiterhin anwendbar. Bei einem einmaligen Übergang zu einem neuen Stil werden diese Regeln jedoch überall einheitlich auf Pfade angewendet, und Sie müssen sich beim Verschieben von Code weniger um Importe kümmern.


Rohe Bezeichner


Sie können jetzt Schlüsselwörter als Bezeichner mit der folgenden neuen Syntax verwenden:


 //      `for` let r#for = true; //     `for` fn r#for() { // ... } //    r#for(); 

Bisher gibt es nicht viele Fälle, in denen dies für Sie nützlich ist. Aber eines Tages werden Sie versuchen, das Paket für Rust 2015 in einem Projekt für Rust 2018 zu verwenden oder umgekehrt, dann werden die Schlüsselwörter anders sein. Wir werden in der kommenden Ankündigung von Rust 2018 mehr darüber sprechen.


Anwendungen ohne Standardbibliothek


Zurück in Rust 1.6 haben wir die Stabilisierung von "no_std" und libcore angekündigt , um Projekte ohne Standardbibliothek zu erstellen. Mit einer Klarstellung: Es war möglich, nur Bibliotheken, aber keine Anwendungen zu erstellen.


In Rust 1.30 können Sie das Attribut #[panic_handler] , um Panik unabhängig zu implementieren. Dies bedeutet, dass Sie jetzt Anwendungen erstellen können, nicht nur Bibliotheken, die die Standardbibliothek nicht verwenden.


Andere


Eine letzte Sache: In Makros können Sie jetzt Bereichsmodifikatoren wie pub mithilfe des vis Qualifikators vis . Außerdem werden jetzt "Werkzeugattribute" wie #[rustfmt::skip] stabilisiert . Für statische Analysewerkzeuge wie #[allow(clippy::something)] sind sie noch nicht stabil.


Weitere Informationen finden Sie in den Versionshinweisen.


Stabilisierung der Standardbibliothek


Die folgenden APIs wurden in dieser Version stabilisiert :


  • Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
  • Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
  • Iterator::find_map

Darüber hinaus verfügt die Standardbibliothek seit langem über Funktionen zum Entfernen von Leerzeichen auf einer Seite eines Texts, z. B. trim_left . Bei RTL-Sprachen führt die Bedeutung von „rechts“ und „links“ hier jedoch zu Verwirrung. Daher führen wir neue Namen für diese Funktionen ein:


  • trim_left -> trim_start
  • trim_right -> trim_end
  • trim_left_matches -> trim_start_matches
  • trim_right_matches -> trim_end_matches

Wir planen, die alten Namen in Rust 1.33 für veraltet zu erklären (aber natürlich nicht zu löschen).


Weitere Informationen finden Sie in den Versionshinweisen.


Frachtverbesserungen


Die größte Verbesserung von Cargo in dieser Version ist, dass wir jetzt einen Fortschrittsbalken haben!


Demo GIF


Weitere Informationen finden Sie in den Versionshinweisen.


Entwickler 1.30.0


Viele Leute haben zusammen Rust 1.30 erstellt. Ohne jeden von Ihnen hätten wir die Arbeit nicht abschließen können. Vielen Dank!


Von einem Übersetzer: Ich danke den Mitgliedern der Rustycrate-Community und persönlich vitvakatu und Virtuos86 für ihre Hilfe bei der Übersetzung und beim Korrekturlesen.

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


All Articles