Programmiersprache Rust 1.61 kann Programme aussagekräftig beenden
![](https://heise.cloudimg.io/width/700/q75.png-lossy-75.webp-lossy-75.foil1/_www-heise-de_/imgs/18/3/5/4/7/7/9/9/Rust.jpg-7e8feee13c67deee.jpeg)
(Bild: Callum Bainbridge / Shutterstock.com)
Neben einem frei gestaltbaren Rückgabewert der main-Funktion bietet das Release Erweiterungen bei konstanten Funktionen.
Im planmäßigen Sechswochentakt ist Rust 1.61 erschienen. Nachdem das vorige Release vor allem Ergänzungen in der Toolchain an Bord hatte, bringt das aktuelle einige Ergänzungen für die Sprache selbst. Unter anderem lassen sich für die Funktion main
neuerdings flexible Rückgabewerte nutzen, und die konstanten Funktionen werden flexibler im Zusammenspiel mit Traits und Zeigern.
Aussagekräftiger Ausstieg aus dem Hauptprogramm
In den Anfangszeiten von Rust endete die Funktion main
, die als Einstiegspunkt für typische Programme dient, ohne jede Statusmeldung. Seit Rust 1.26 [1] erlaubt die Programmiersprache die Rückgabe von Result
. Im Zusammenspiel mit C entspricht dabei der Rust-Wert Ok
dem C-Rückgabewert EXIT_SUCCESS
und Err
entspricht EXIT_FAILURE
.
Zuständig für die Rückgabe ist der Trait Termination
. Traits in Rust ähneln Interfaces in anderen Programmiersprachen. Sie definieren eine Reihe von Methoden für einen zunächst unbekannten Typ Self
. Termination
existierte bisher nur unter der Haube und galt als instabil.
Rust 1.61 stabilisiert den Trait und generalisiert im Zuge dessen den Rückgabewert mit dem Typ ExitCode
. Letzterer enthält einerseits die Konstanten SUCCESS
and FAILURE
und implementiert darüber hinaus From<u8>
für beliebige Rückgabewerte. Darüber hinaus lässt sich Termination
mit eigenen Typen verwenden, um zusätzliche Arbeitsschritte vor der Ausgabe des ExitCode
zu definieren.
Folgendes Beispiel aus dem Rust-Blog zeigt den Einsatz des Traits in einer Umsetzung des Git-Befehls bisect run
. Dazu definiert der Code eine Enumeration mit passenden Rückgabewerten:
use std::process::{ExitCode, Termination};
#[repr(u8)]
pub enum GitBisectResult {
Good = 0,
Bad = 1,
Skip = 125,
Abort = 255,
}
impl Termination for GitBisectResult {
fn report(self) -> ExitCode {
// Maybe print a message here
ExitCode::from(self as u8)
}
}
fn main() -> GitBisectResult {
std::panic::catch_unwind(|| {
todo!("test the commit")
}).unwrap_or(GitBisectResult::Abort)
}
Veränderungen am Konstanten
Die zweite große Neuerung betrifft konstante Funktionen, die Rust seit Version 1.31 kennt [2]. Letztere markierte 2018 gleichzeitig den Start der zweiten Edition der Programmiersprache Rust. Eine const fn
lässt sich im Gegensatz zu regulären Funktionen in konstanten Kontexten ausführen, also beispielsweise in einem const
or static
Element. Da der Compiler sie in diesem Kontext beim Übersetzen evaluieren kann, nimmt er in dem Fall zusätzlich erweiterte Optimierungen vor. Außerhalb der Kontexte verhalten konstante Funktionen sich weitgehend wie reguläre, sind aber einigen Beschränkungen unterbunden.
Seit dem ersten Aufschlag hat Rust einige Ergänzungen für die konstanten Funktionen mitgebracht, unter anderem in der Version 1.33 [3] und in Rust 1.46 [4]. Das aktuelle Release beseitigt nun einige Beschränkungen für const fn
. Unter anderem lassen sich Funktions-Pointer erstellen, übergeben und casten. Allerdings ist es nach wie vor nicht erlaubt, die fn
-Zeiger direkt aufzurufen.
Im Zusammenspiel mit Traits erlaubt Rust 1.61 für konstante Funktionen Trait Bounds mit generischen Parametern wie T: Copy
. Außerdem können sie dyn Trait
-Typen für Objekte, deren genaues Speicher-Layout erst zur Laufzeit bekannt ist, und generischere impl Trait
-Typen verarbeiten. Der Aufruf von Methoden der Traits aus der konstanten Funktion ist jedoch noch nicht erlaubt.
Auf Lebenszeit gesperrt
Nennenswert ist noch, dass das Absichern von Daten in Standard-Streams vor Überschreiben bei nebenläufiger Programmierung über lock()
neuerdings im statischen Verlaufskontext erfolgt. Bisher war nur ein Lock Guard auf &self
für Stdin
, Stdout
und Stderr
möglich, womit das Absichern auf den ursprünglichen Scope beschränkt war. Nun erfolgt der Lock Guard über die gesamte Lebenszeit des Programms, also der Lifetime [5] 'static
.
Weitere Details zu Rust 1.61, darunter einige stabilisierte APIs, lassen sich dem Rust-Blog entnehmen [6]. Wie üblich können Entwicklerinnen und Entwickler, die Rust bereits installiert haben, das aktuelle Release über rustup update stable
herunterladen. Für diejenigen, die noch kein Rust verwenden, ist das rustup
-Tool auf der Download-Seite separat verfügbar.
Siehe auch:
- Rust [7]: Download schnell und sicher von heise.de
(rme [8])
URL dieses Artikels:
https://www.heise.de/-7101438
Links in diesem Artikel:
[1] https://www.heise.de/news/Programmiersprache-Rust-1-26-fuehrt-Existential-Types-ein-4047326.html
[2] https://www.heise.de/news/Programmiersprache-Rust-1-31-markiert-den-Start-von-Rust-2018-4244887.html
[3] https://www.heise.de/news/Programmiersprache-Rust-1-33-kann-Daten-im-Speicher-verankern-4324047.html
[4] https://www.heise.de/news/Mehr-Power-in-Rust-1-46-durch-erweiterten-Einsatz-konstanter-Funktionen-4881094.html
[5] https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html
[6] https://blog.rust-lang.org/2022/05/19/Rust-1.61.0.html
[7] https://www.heise.de/download/product/rust-96655
[8] mailto:rme@ix.de
Copyright © 2022 Heise Medien