Die Veröffentlichung der Programmiersprache Rust 1.82 ist da, die ursprünglich von Mozilla entwickelt wurde, jedoch nun von der unabhängigen gemeinnützigen Organisation Rust Foundation weitergeführt wird. Die Sprache legt einen Schwerpunkt auf sichere Speicherverwaltung und bietet Mittel für hohen Parallelismus bei der Ausführung von Aufgaben, ohne dabei auf einen Garbage Collector und Runtime (Runtime beschränkt sich auf die grundlegende Initialisierung und die Pflege der Standardbibliothek) angewiesen zu sein.
Die Speicherverwaltungsmethoden in Rust befreien Entwickler von Fehlern beim Umgang mit Zeigern und schützen vor Problemen, die durch die Programmierung auf niedriger Ebene entstehen, wie z.B. den Zugriff auf freigegebenen Speicher, Dereferenzierung von Nullzeigern, Pufferüberläufe usw. Zur Verteilung von Bibliotheken, zur Gewährleistung des Builds und zum Management von Abhängigkeiten wird der Paketmanager Cargo entwickelt. Für die Bereitstellung von Bibliotheken wird das Repository crates.io unterstützt.
Die sichere Handhabung von Speicher in Rust wird während der Kompilierung durch die Überprüfung von Referenzen, das Verfolgen des Besitztums von Objekten, das Management der Lebensdauer von Objekten (Sichtbarkeitsbereiche) und die Bewertung der Korrektheit des Zugriffs auf den Speicher zur Laufzeit sichergestellt. Rust bietet außerdem Mechanismen zum Schutz vor ganzzahligen Überläufen, erfordert die verpflichtende Initialisierung von Variablenwerten vor der Verwendung, behandelt Fehler in der Standardbibliothek effektiver, implementiert das Konzept der Unveränderlichkeit (immutable) von Referenzen und Variablen standardmäßig und bietet eine starke statische Typisierung zur Minimierung logischer Fehler.
Hauptneuheiten:
- Das Paketmanagement-Tool Cargo erhielt den Befehl „info“, um Informationen über das Paket im Repository anzuzeigen.
- Die Unterstützung der Syntax „use<..>“ in „impl Trait“ wurde hinzugefügt, die Informationen über versteckte Typen definiert. Zum Beispiel zeigt „impl Trait + use<‘x, T>“ an, dass im versteckten Typ nur die Parameter „x“ und „T“ verwendet werden dürfen.
- Ein neuer Syntax zur Erstellung von Raw-Zeigern wurde vorgestellt, der die zuvor verwendeten Makros ersetzt: Anstelle des Makros „addr_of!(expr)“ wird der Operator „&raw const expr“ verwendet, und anstelle des Makros „addr_of_mut!(expr)“ kommt der Operator „&raw mut expr“. struct Packed { not_aligned_field: i32, } fn main() { let p = Packed { not_aligned_field: 1_82 }; // Alte Methode zur Erstellung eines Raw-Zeigers let ptr = std::ptr::addr_of!(p.not_aligned_field); // Neue Methode zur Erstellung eines Raw-Zeigers let ptr = &raw const p.not_aligned_field; let val = unsafe { ptr.read_unaligned() }; }
- Die Möglichkeit, sichere (safe) Funktionen und Konstanten mit einer Lebensdauer von ‚static‘ innerhalb von extern-Blöcken mit dem Attribut „unsafe“ zu definieren, wurde eingeführt (früher konnten alle Elemente in „unsafe extern“ nur mit dem Attribut „unsafe“ versehen werden): unsafe extern { pub safe static TAU: f64; pub safe fn sqrt(x: f64) -> f64; pub unsafe fn strlen(p: *const u8) -> usize; }
- Die Attribute no_mangle, link_section und export_name, die zu undefiniertem Verhalten führen können, gelten jetzt als unsicher und erfordern eine ausdrückliche Kennzeichnung mit dem Attribut „unsafe“, zum Beispiel: #[unsafe(no_mangle)] pub fn my_global_function() { }
- Beim Abgleich mit der Vorlage dürfen leere Typen wie „enum Void {}“ oder Strukturen mit sichtbarem leeren Feld übergangen werden. use std::convert::Infallible; pub fn unwrap_without_panic(x: Result) -> T { let Ok(x) = x; // „Err“ kann übergangen werden x }
- Bei Gleitkommatypen (f32 und f64) wurde das Verhalten bei der Verarbeitung von nicht-numerischen Werten NaN (0.0/0.0) standardisiert, und die Verwendung von Gleitkommaoperationen in const fn wurde ebenfalls erlaubt.
- In Inline-Assembly wurde die Möglichkeit geschaffen, Operanden mit dem Attribut „const“ zu verwenden, um Ganzzahlen direkt zu verwenden, ohne sie zuvor in ein Register zu speichern. const MSG: &str = "Hello, world!\n"; unsafe { core::arch::asm!( "mov rdx, {LEN} // die Anweisung 'mov rdx, 14' wird generiert", LEN = const MSG.len(), … ); }
- Die Adressierung von Ausdrücken mit dem Merkmal "static" ist im sicheren Kontext ohne Definition eines unsicheren Blocks erlaubt (die Operatoren "&raw mut" und "&raw const" beeinflussen nicht den Wert des Operanden und erstellen lediglich einen Zeiger darauf): static mut STATIC_MUT: Type = Type::new(); extern "C" { static EXTERN_STATIC: Type; } fn main() { let static_mut_ptr = &raw mut STATIC_MUT; let extern_static_ptr = &raw const EXTERN_STATIC; }
- Eine neue Reihe von APIs wurde stabilisiert und in die stabile Version überführt, einschließlich stabilisierter Methoden und Implementierungen von Traits:
- std::thread::Builder::spawn_unchecked
- std::str::CharIndices::offset
- std::option::Option::is_none_or
- [T]::is_sorted
- [T]::is_sorted_by
- [T]::is_sorted_by_key
- Iterator::is_sorted
- Iterator::is_sorted_by
- Iterator::is_sorted_by_key
- std::future::Ready::into_inner
- std::iter::repeat_n
- impl DoubleEndedIterator für Take
Quelle: opennet.ru
