Da ich aus anderen funktionalen Sprachen komme (und ein Rust-Neuling bin), bin ich etwas überrascht von der Motivation von Rust's if let
-Syntax. Der RFC erwähnt das ohne if let
, die "idiomatische Lösung heute zum Testen und Auspacken eines Option<T>
". "ist entweder
oder
%Vor% In Scala wäre es möglich, genau dasselbe zu tun. Aber die idiomatische Lösung ist eher zu map
über einem Option
(oder zu foreach
, wenn es nur für den Nebeneffekt von doing_something_with(x)
ist).
Meine Frage ist also: Warum ist es nicht eine idiomatische Lösung, das gleiche in Rust zu tun:
%Vor% map()
ist für transforming ein optionaler Wert, während if let
meistens benötigt wird, um Nebeneffekte auszuführen. Während Rust keine reine Sprache ist, so dass jeder seiner Codeblöcke Nebenwirkungen enthalten kann, ist die Kartensemantik immer noch da. Die Verwendung von map()
zur Ausführung von Nebenwirkungen, die sicherlich möglich ist, wird Leser Ihres Codes nur verwirren. Beachten Sie, dass es zumindest im einfachen Code keine Leistungseinbußen geben sollte - der LLVM-Optimierer ist perfekt in der Lage, den Abschluss direkt in die aufrufende Funktion einzubinden, so dass er einer match
-Anweisung entspricht.
Vor if let
war die einzige Möglichkeit, Nebenwirkungen in Option
auszuführen, entweder eine Übereinstimmung oder if
mit Option::is_some()
check. match
approach ist am sichersten, aber es ist sehr ausführlich, besonders wenn viele verschachtelte Checks benötigt werden:
Beachten Sie die auffällige Rechtsdrift und eine Menge syntaktisches Rauschen. Und es wird nur noch schlimmer, wenn Zweige keine einfachen Übereinstimmungen sind, sondern richtige Blöcke mit mehreren Anweisungen.
if option.is_some()
approach ist dagegen etwas weniger ausführlich, liest sich aber immer noch sehr schlecht. Auch seine Bedingungsprüfung und unwrap()
sind nicht statisch verknüpft, so dass es möglich ist, es falsch zu verstehen, ohne dass der Compiler es merkt.
if let
löst das Problem der Ausführlichkeit, basiert auf der gleichen Musterzusammenfassung wie match
(daher ist es schwerer falsch zu verstehen als if option.is_some()
) und erlaubt als Nebeneffekt die Verwendung beliebiger Typen in Mustern nur Option
. Zum Beispiel bieten einige Typen möglicherweise keine map()
-like-Methoden; if let
wird immer noch sehr gut mit ihnen arbeiten. So if let
ist ein klarer Gewinn, daher ist es idiomatisch.
Weil Ihre Lösung einen Abschluss erstellt, der Ressourcen verwendet, während if let
exakt auf Ihr erstes Beispiel verweist, was nicht der Fall ist. Ich finde es auch lesbarer.
Bei Rust geht es um Null-Kosten-Abstraktionen, die die Programmierung angenehmer machen, und if let
und while let
sind gute Beispiele dafür (zumindest IMO - ich weiß, dass es eine Frage der persönlichen Präferenz ist). Sie sind nicht unbedingt notwendig, aber sie fühlen sich gut an zu benutzen (siehe auch: Clojure, wo sie wahrscheinlich aufgehoben wurden).