Warum benötigt Rust die 'if let'-Syntax?

7

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

%Vor%

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%     
bluenote10 17.12.2014, 20:33
quelle

3 Antworten

8

.map() ist spezifisch für den Option<T> -Typ, aber if let (und while let !) sind Funktionen, die mit allen Rust-Typen funktionieren.

    
bluss 17.12.2014, 20:56
quelle
13

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:

%Vor%

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.

    
Vladimir Matveev 17.12.2014 21:16
quelle
2

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).

    
Max Noel 17.12.2014 20:37
quelle

Tags und Links