Die Veröffentlichung der Programmiersprache Rust 1.82, die ursprünglich von Mozilla entwickelt und nun von der unabhängigen Non-Profit-Organisation Rust Foundation weiterentwickelt wird, wurde veröffentlicht. Die Sprache konzentriert sich auf eine sichere Arbeit mit dem Speicher und bietet Mittel für hohe Parallelität bei der Aufgabenausführung, ohne einen Garbage Collector oder Runtime zu benötigen (die Runtime beschränkt sich auf die grundlegende Initialisierung und die Verwaltung der Standardbibliothek).
Die Methoden zur Speicherverwaltung in Rust befreien den Entwickler von Fehlern beim Umgang mit Zeigern und schützen vor Problemen, die durch niedrige Speicherverwaltung entstehen, wie z. B. den Zugriff auf Speicherbereiche nach deren Freigabe, Dereferenzierung von Nullzeigern, Pufferüberläufen usw. Zur Verbreitung von Bibliotheken, zur Gewährleistung des Builds und zur Verwaltung von Abhängigkeiten wird der Paketmanager Cargo entwickelt. Für das Hosting von Bibliotheken wird das Repository crates.io unterstützt.
Sichere Speicherverwaltung wird in Rust während der Kompilierung durch Überprüfung von Referenzen, Nachverfolgung des Eigentums an Objekten, Berücksichtigung der Lebensdauer von Objekten (Sichtbarkeitsbereiche) und Bewertung der Korrektheit des Zugriffs auf den Speicher während der Ausführung des Codes gewährleistet. Rust bietet ebenfalls Mittel zum Schutz vor Überläufen bei Ganzzahlen, fordert die zwingende Initialisierung von Variablenwerten vor deren Verwendung und behandelt Fehler in der Standardbibliothek besser. Außerdem wird das Konzept der Unveränderlichkeit (immutable) von Referenzen und Variablen standardmäßig angewendet, und es bietet eine starke statische Typisierung zur Minimierung logischer Fehler.
Hauptneuheiten:
- Das Paketverwaltungssystem cargo hat den Befehl „info“ hinzugefügt, um Informationen über ein Paket im Repository auszugeben.
- Die Unterstützung der Syntax „use<..>“ in „impl Trait“ wurde hinzugefügt, die Informationen über verborgene Typen definiert. Zum Beispiel bedeutet „impl Trait + use<‘x, T>“, dass im verborgenen Typ nur die Parameter „x“ und „T“ zulässig sind.
- Eine separate Syntax zur Erstellung von Raw-Pointern wurde vorgeschlagen, die die zuvor verwendeten Makros ersetzt: Anstelle des Makros „addr_of!(expr)“ kam der Operator „&raw const expr“, und anstelle des Makros „addr_of_mut!(expr)“ 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-Pointers let ptr = std::ptr::addr_of!(p.not_aligned_field); // Neue Methode zur Erstellung eines Raw-Pointers let ptr = &raw const p.not_aligned_field; let val = unsafe { ptr.read_unaligned() }; }
- Es wird die Möglichkeit bereitgestellt, sichere (safe) Funktionen und Konstanten mit der Lebensdauer ‘static’ innerhalb von extern-Blöcken mit dem Zeichen „unsafe“ zu definieren (zuvor konnten alle Elemente in „unsafe extern“ nur das Zeichen „unsafe“ haben): 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 nicht definiertem Verhalten führen können, gelten nun als unsicher und erfordern eine explizite Kennzeichnung mit dem Zeichen „unsafe“, zum Beispiel: #[unsafe(no_mangle)] pub fn my_global_function() { }
- Beim Mustervergleich ist es erlaubt, leere Typen wie „enum Void {}“ oder Strukturen mit sichtbarem leerem Feld zu überspringen. use std::convert::Infallible; pub fn unwrap_without_panic<T>(x: Result<T, Infallible>) -> T { let Ok(x) = x; // „Err“ kann übersprungen werden x }
- Das Verhalten im Umgang mit nicht-numerischen Werten NaN (0.0/0.0) wurde für Typen für Fließkommazahlen (f32 und f64) standardisiert, und die Verwendung von Fließkommaoperationen in const fn wurde genehmigt.
- In den Assembler-Insertionen besteht die Möglichkeit, Operanden mit dem Attribut „const“ zu verwenden, um ganze Zahlenwerte direkt zu nutzen, ohne sie zuvor in einem Register zu speichern. const MSG: &str = "Hello, world!\n"; unsafe { core::arch::asm!( "mov rdx, {LEN} \/\/ Es wird die Anweisung 'mov rdx, 14' erstellt", LEN = const MSG.len(), … ); }
- Die Adressierung von Ausdrücken mit dem Attribut „static“ ist im sicheren Kontext ohne Definition eines unsicheren Blocks erlaubt (die Operatoren „&raw mut“ und „&raw const“ beeinflussen den Wert des Operanden nicht 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 Charge von APIs wurde in den stabilen Bereich überführt, darunter wurden Methoden und Implementierungen von Traits stabilisiert:
- 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 for Take
Quelle: opennet.ru
