Rust 1.35.0 Release: Implementierungen funktionaler Merkmale und andere Innovationen

Ich präsentiere Ihnen eine Übersetzung der Veröffentlichung zur neuen Version der beliebtesten Programmiersprache Rust .


Einführung


Das Team der Programmiersprache Rust freut sich, eine neue Version 1.35.0 bekannt zu geben. Rust ist eine Programmiersprache, mit der jeder zuverlässige und schnelle Software entwickeln kann.


Wenn Sie die vorherige Version von Rust mit rustup installiert rustup , ist es nicht schwierig, die aktuelle Version zu erhalten:


 $ rustup update stable 

Wenn Sie immer noch kein rustup , können Sie es von der entsprechenden Seite auf unserer Website erhalten. Eine ausführliche Rezension dieser Version ist auf GitHub verfügbar.


Was ist in der stabilen Version enthalten?


Zu den Hauptinnovationen dieser Version gehört die Implementierung der FnMut FnOnce, FnMut und Fn in den Box<dyn FnOnce> , Box<dyn FnMut> und Box<dyn Fn> .


Neben Inline-Funktionen (Closures) können auch unsichere Funktionszeiger konvertiert werden. Makro dbg! Die in Rust 1.32.0 eingeführte Version kann jetzt ohne Angabe von Argumenten aufgerufen werden.


Darüber hinaus führte diese Version viele Stabilisierungen der Standardbibliothek ein. Nachfolgend sind die wichtigsten aufgeführt, von denen jedoch eine detaillierte Analyse verfügbar ist.


Auf Box<dyn Fn*> implementierte Box<dyn Fn*>


In Rust 1.35.0 sind die FnOnce , FnMut und Fn in Box<dyn FnOnce> , Box<dyn FnMut> bzw. Box<dyn Fn> Box<dyn FnMut> .


Wenn Sie in der Vergangenheit eine in Box<T> gekapselte Funktion aufrufen wollten, mussten Sie FnBox , da Box<dyn FnOnce> -Objekte und dergleichen die entsprechenden Fn* Box<dyn FnOnce> nicht implementierten. Es wurde auch die Übertragung von gekapselten Funktionen in Box<T> an den Code verhindert, der auf den Fn Trait-Implementierer wartete (es wurde vorgeschlagen, temporäre Inline-Funktionen zu erstellen).


Dies wurde durch die Unfähigkeit des Compilers verursacht, solche Implementierungen zu erkennen. Dieser Fehler wurde mit der Einführung von unsized_locals .


Jetzt können Sie die in Box<T> gekapselten Funktionen jedoch auch an Stellen verwenden, an denen die Implementierung eines Funktionsmerkmals erwartet wird. Der folgende Code wird beispielsweise fehlerfrei kompiliert:


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

Box<dyn FnOnce> können ohne Box<dyn FnOnce> aufgerufen werden:


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

Konvertieren in unsichere Zeiger


Seit Rust 1.19.0 ist es möglich geworden, eingebettete Funktionen, die die Umgebung nicht erfassen, in Funktionszeiger umzuwandeln. Zum Beispiel könnten Sie schreiben:


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

Leider wurde diese Funktion nicht auf unsichere Funktionszeiger erweitert. Diese Version führte die oben beschriebenen Änderungen ein:


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

Rufen Sie dbg!() Ohne Argumente auf


Aufgrund der Fülle an println! Anrufen println! Als kollektive Farm-Debugger wurde das dbg! Makro in Rust 1.32.0 eingeführt dbg! . Denken Sie daran, dass Sie mit diesem Makro schnell das Ergebnis eines bestimmten Ausdrucks mit Kontext erfassen können:


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

Die obigen Codezeilen drucken das Ergebnis des Ausdrucks x == 1 bzw. x auf das Terminal:


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

Wie im vorherigen Abschnitt erwähnt, in dem eine Funktion höherer Ordnung call_unsafe_fn_ptr kann, soll dbg!() Auch ohne Angabe von Argumenten aufgerufen werden. Dies kann äußerst nützlich sein, um ausgewählte Programmzweige zu ermitteln:


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

Stabilisierung der Standardbibliothek


In Rust 1.35.0 wurden viele Komponenten der Standardbibliothek stabilisiert. Darüber hinaus wurden einige Implementierungen eingeführt, über die Sie hier lesen können.


Kopieren Sie das Vorzeichen einer Gleitkommazahl auf eine andere Zahl


Mit dieser Version wurden Gleitkomma- f32 (insbesondere f32 und f64 ) neue copysign Methoden hinzugefügt:



Wie der Name der vorgeschlagenen Methoden schon sagt, können Sie damit das Vorzeichen einer Zahl in eine andere kopieren:


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

Überprüfen, ob Range einen bestimmten Wert enthält


Rust 1.35.0 hat einige neue Methoden für Range* -Strukturen erworben:



Mit diesen Methoden können Sie leicht überprüfen, ob ein bestimmter Wert in einem Bereich liegt. Zum Beispiel können Sie schreiben:


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

Übersetzen Sie (Karte) und teilen Sie geliehene RefCell


Mit dem Aufkommen von Rust 1.35.0 können Sie den geliehenen RefCell Wert in eine Reihe geliehener Werte in verschiedene Komponenten der geliehenen Daten übersetzen und aufteilen:



RefCell Wert über die Inline-Funktion aus


In dieser Version wird die praktische Methode replace_with eingeführt, die in der RefCell Struktur RefCell ist:



Hash einen Zeiger oder Link zu


In dieser Version wird die Funktion ptr::hash , die einen Rohzeiger für das Hashing verwendet. Die Verwendung von ptr::hash kann den Hash eines angegebenen oder referenzierten Werts anstelle der Adresse selbst verhindern.


Kopieren Sie die Option<&T>


Mit Beginn von Rust 1.0.0 ermöglichten die Option::cloned Methoden für Option<&T> und Option<&mut T> das Klonen des Inhalts, falls vorhanden ( Some(_) ). Das Klonen kann jedoch manchmal eine teure Operation sein, und die opt.cloned() -Methoden haben keine Hinweise beschrieben.


Diese Version hat dazu beigetragen:



Die Funktionalität von opt.copied() der von opt.cloned() . Das oben beschriebene Verfahren fordert jedoch die Bedingungen T: Copy , deren Fehler einen Kompilierungsfehler verursachen.


Clippy Änderungen


Clippy, ein Tool, das häufig auftretende Mängel zur Verbesserung der Codequalität drop_bounds , hat drop_bounds erworben. Es funktioniert, wenn die verallgemeinerte Funktion nach der Erfüllung der Bedingung T: Drop fragt T: Drop :


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

Dies ist häufig ein Fehler, da Grundelemente Drop nicht implementieren. Darüber hinaus deckt T: Drop keine Typen wie String , die kein destruktives Verhalten aufweisen, sondern das Ergebnis von Inline-Typen (wie Vec<u8> ).


Zusätzlich zu drop_bounds teilt diese Version redundant_closure in redundant_closure und redundant_closure_for_method_calls .


Lesen Sie hier die detaillierte Version von Clippy.


Änderungen in der Fracht


Eine detaillierte Beschreibung der Frachtänderungen finden Sie hier .


Mitglieder 1.35.0


Viele Leute kamen zusammen, um Rust 1.35.0 zu erstellen. Ohne euch alle hätten wir das nicht geschafft, danke !


Vom Übersetzer


Bei Fragen zur Rust-Sprache können sie Ihnen im russischsprachigen Telegramm-Chat oder in einem ähnlichen Chat für Neulinge helfen.

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


All Articles