Am Tag der Feier zum zehnjährigen Jubiläum der Veröffentlichung der Programmiersprache Rust 1.0 (das Rust-Projekt wurde 2006 gegründet, die Version 0.1 wurde 2012 erstellt und die erste stabile Version wurde 2015 angeboten) wurde die Version Rust 1.87 veröffentlicht. Die Sprache konzentriert sich auf die sichere Handhabung von Speicher und bietet Mittel zur Erreichung hohen Parallelismus bei der Ausführung von Aufgaben, ohne einen Garbage Collector und Runtime zu verwenden (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:
- Die Standardbibliothek wurde um die Unterstützung für anonyme Pipes (nicht benannte Kanäle) erweitert. Zum Erstellen nicht benannter Kanäle wurde die Methode std::io::pipe() vorgeschlagen, die zusammen mit std::process::Command zur Bearbeitung von Standard-Ein- und Ausgabeströmen sowie zur Zusammenführung der stdout- und stderr-Ströme verwendet werden kann. use std::process::Command; use std::io::Read; let (mut recv, send) = std::io::pipe()?; let mut command = Command::new("path/to/bin") // Kombination von stdout und stderr in einem Kanal .stdout(send.try_clone()?) .stderr(send) .spawn()?; let mut output = Vec::new(); recv.read_to_end(&mut output)?; assert!(command.wait()?.success());
- Der Aufruf der meisten im Compiler eingebauten Funktionen (Intrinsics) std::arch aus sicherem Code ist erlaubt. Die Änderung gilt für die eingebauten Funktionen std::arch, die nur wegen der Bindung an bestimmte Funktionalitäten als unsicher markiert sind, wenn diese Funktionalitäten aktiviert sind. Zum Beispiel kann _mm256_add_epi32 aus sicherem Code aufgerufen werden, wenn in der Anwendung '#[target_feature(enable = "avx2")]' verwendet wird.
- Aus Blöcken mit Assembler-Code, die mit "asm!" gekennzeichnet sind, sind Sprünge zu Blöcken mit Rust-Code erlaubt, was die Entwicklung von niedrigstufigem Code vereinfacht, zum Beispiel zur Umsetzung von Optimierungen im Kern oder zur Organisation der Interaktion mit der Hardware. Der Sprungpunkt für den Assemblerbefehl "jmp" wird im Makro "asm!" durch einen neuen Operand "label" festgelegt, der einen Blockausdruck mit Rust-Code enthält. unsafe { asm!( "jmp {}", label { println!("Von asm! gesprungen!"); } ); }
- Es ist erlaubt, die erfassten generischen Typen und Lebensdauern in den Definitionen der Trait-Typen unter Verwendung der Rückgabewerte impl Trait genau anzugeben. 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; }
- Eine neue Charge von APIs wurde in den stabilen Bereich überführt, darunter wurden Methoden und Implementierungen von Traits stabilisiert:
- 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
- Das Merkmal «const» wird in Funktionen angewendet:
- 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
- Der zweite Unterstützungsgrad für die Zielplattform i586-pc-windows-msvc wurde entfernt. Es wird empfohlen, die Plattform i686-pc-windows-msvc zu verwenden, die Unterstützung für SSE2-Befehle bietet. Die Plattform i586-pc-windows-msvc hat an Bedeutung verloren, da für Windows 10 die Unterstützung von SSE2 erforderlich ist, während frühere Windows-Versionen in Rust nicht unterstützt werden.
Quelle: opennet.ru
