Was ist der Vorteil der Verwendung einer Folge?
Ich verstehe nicht, warum Result
existiert in Rust. Ich kann sehen, wie Option
können nützlich sein, aber mit Result
scheint nur zu erschweren-code unnötig.
Betrachten Sie das folgende Beispiel:
#[derive(PartialEq, Eq, Debug)]
enum MyErr {
None,
FailOne,
}
fn returns_tuple() -> (u8, MyErr) {
//(1, None) //<-- Success path
(0, MyErr::FailOne)
}
fn returns_result() -> Result<u8, MyErr> {
//Ok(1) //<-- Success path
Err(MyErr::FailOne)
}
#[test]
fn test_check_return_values() {
let x = returns_result();
if x.is_ok() {
println!("result: Is OK: {}", x.unwrap()); //<-- Must use unwrap
} else {
match x.err().unwrap() { //<-- Again, unwrapping
MyErr::None => {}, //Required for match
MyErr::FailOne => println!("result: Failed One"),
}
}
}
#[test]
fn test_check_return_values_2() {
let (y, err) = returns_tuple();
match err {
MyErr::None => println!("tuple: Is OK: {}", y),
MyErr::FailOne => println!("tuple: Failed one"),
}
}
Das einzige, was ich sehen kann ist, dass es minorly erhöht die Bequemlichkeit der Funktion Schriftsteller, wie Sie können, rufen Sie einfach Ok()
und Err()
Ergebnisse zurückgegeben.
Ich habe gesehen, einige Leute sagen, die so Sie können Bedingungen verwenden, aber das ist überhaupt nicht wahr; Sie können Bedingungen verwenden, perfekt auch mit Tupeln. (Hinweis — "Bedingungen" waren eine Funktion von Rost, die entfernt wurden, bevor 1.0)
Habe ich auch gesehen, einige Leute sagen, dass Result
ist performant, dass wieder ein Tupel, aber Result
ist ein Tupel, also ich sehe nicht, wie das der Fall sein kann.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Betrachten wir die definition von
Ergebnis
:Destilliert, um die bits, die Materie, es
enum Result<T, E> { Ok(T), Err(E) }
.Nicht ein Tupel
(T, E)
; vielmehr ist es entweder eineT
(OK) oder eineE
(Fehler).Wenn Sie verwenden ein Tupel
(T, E)
müssen Sie definieren, sowohl dieT
und dieE
. Für Ihrereturns_tuple
, das bedeutete, dass die Definition von 0 als Magie-Wert und das hinzufügen einer neuen Variante auf IhremMyErr
AufzählungNone
.None
ist kein Fehler; es ist semantisch inkorrekt zu Modell ist es so. Es wird auch dann propagiert, um an anderen Orten wegen der Voraussetzung der erschöpfenden passenden.Beim Umgang mit komplexeren Typen, definieren eine dummy-Wert kann weniger möglich oder teurer. Als eine Verallgemeinerung, mit dummy-Werten ist nicht ein guter plan. Es ist viel zu wahrscheinlich, dass irgendwo auf dem Weg Sie werden tatsächlich versuchen, zu verwenden Sie.
Rost ist ein guter Typ-system, das Ihnen erlaubt, um zu vermeiden, dass diese Arten von Problemen.
Sieht es für mich wie Sie vielleicht verpasst haben, die macht der Rost ist matching; in der Tat, der einzige Weg, um einen Wert aus einer enum-pattern-matching; in der Folge Dinge wie
Result.ok()
,Result.err()
undOption.unwrap()
umgesetzt werden, in Bezug auf pattern-matching.Nun schreiben wir Ihrem Beispiel in einer Weise, die zeigt, dass Rust in einem besseren Licht.
Result
dient als Dokumentation durch die Benennung seiner möglichen Werte. Dies mag gering erscheinen, aber die Realität ist, wenn Sie schreiben eine ganze Menge code, die Sie benötigen, zu betrachten, die Dokumente für Funktionen, die Rückkehr(a, b)
zu wissen, was Los ist, die für bestimmte; wer weiß, wenn Sie sind der Rückgabe 1 oder 0 bei Erfolg oder wenn es ein Fehler ist Wert überhaupt? Wenn ich rufe eine Funktion erwartet einenFoo
und ich bekommeResult<Foo, _>
, ich weiß sicher, dass es der Umgang mit einem möglichen Fehler, und ich weiß ohne Frage, die return-Werte sind Erfolg Werte (diejenigen, eingewickelt inOk
).