Am Tag der Feierlichkeiten zum zehnjährigen Bestehen 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 veröffentlicht) wurde das Release von Rust 1.87 veröffentlicht. Die Sprache konzentriert sich auf die sichere Arbeit mit Speicher und bietet Werkzeuge für hohen Parallelismus bei der Ausführung von Aufgaben, ohne dabei einen Garbage Collector und Runtime (die Runtime beschränkt sich auf die grundlegende Initialisierung und die Unterstützung der Standardbibliothek) zu verwenden.
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:
- Die Standardbibliothek hat Unterstützung für anonyme Pipes (anonymous pipe) hinzugefügt. Um anonyme Pipes zu erstellen, wurde die Methode std::io::pipe() vorgeschlagen, die in Kombination mit std::process::Command zur Verarbeitung von Standard-Eingabe- und -Ausgabeströmen verwendet werden kann und zudem die Streams stdout und stderr zusammenführen kann. use std::process::Command; use std::io::Read; let (mut recv, send) = std::io::pipe()?; let mut command = Command::new("path/to/bin") // Zusammenführen von stdout und stderr in einen 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 aus sicherem Code für die meisten in den Compiler integrierten Funktionen (Intrinsics) std::arch ist erlaubt. Die Änderung gilt für die integrierten Funktionen std::arch, die nur aufgrund der Bindung an spezifische Funktionalitäten als unsicher markiert sind, sofern diese Funktionalitäten aktiviert sind. Zum Beispiel kann _mm256_add_epi32 aus sicherem Code aufgerufen werden, wenn die Anwendung '#[target_feature(enable = "avx2")]' verwendet.
- Sprünge von 'asm!' Blöcken mit Assemblersprache-Code zu Rust-Code Blöcken sind erlaubt, was die Entwicklung von Low-Level-Code erleichtert, wie beispielsweise die Implementierung von Optimierungen im Kernel oder die Organisation der Interaktion mit der Hardware. Der Sprungpunkt für den Assembler-Befehl 'jmp' wird im 'asm!' Makro durch einen neuen Operanden 'label' festgelegt, der einen Blockausdruck mit Rust-Code enthält. unsafe { asm!( 'jmp {}', label { println!( 'Vom asm! gesprungen!'); } ); }
- Es ist erlaubt, die erfassten allgemeinen Typen und Lebenszeiten in den Typdefinitionen mit den zurückgegebenen Typen 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 Reihe von APIs wurde stabilisiert und in die stabile Version überführt, einschließlich stabilisierter Methoden und Implementierungen von Traits:
- 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 Kennzeichen „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
- Die Unterstützung der zweiten Ebene für die Zielplattform i586-pc-windows-msvc wurde eingestellt. Es wird empfohlen, die Plattform i686-pc-windows-msvc zu verwenden, die 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, und frühere Windows-Versionen werden in Rust nicht mehr unterstützt.
Quelle: opennet.ru
