2017-08-03 3 views
0

Die Rust documentation gives this example passend, wo wir haben eine Instanz von Result<T, E>some_value genannt:von einem ENUM ohne Muster lesen

match some_value { 
    Ok(value) => println!("got a value: {}", value), 
    Err(_) => println!("an error occurred"), 
} 

Gibt es eine Möglichkeit von some_value ohne Mustervergleich zu lesen? Was ist, ohne den Typ des Inhalts zur Laufzeit zu überprüfen? Vielleicht wissen wir irgendwie mit absoluter Sicherheit, welcher Typ enthalten ist, oder vielleicht sind wir nur ein schlechter Programmierer. In jedem Fall bin ich nur neugierig zu wissen, ob es überhaupt möglich ist, nicht, ob es eine gute Idee ist.

Es scheint mir ein wirklich interessantes Sprachmerkmal, dass dieser Zweig so schwierig (oder unmöglich?) Zu vermeiden ist.

+1

Verwandte/möglich Duplikat: https://stackoverflow.com/questions/34953711/unwrap-inner-type-when-enum-variant-is-known –

Antwort

7

Auf der untersten Ebene, nein, können Sie keine enum Felder ohne eine match lesen.

Methoden auf einer Enumeration können einen bequemeren Zugriff auf Daten innerhalb der Enumeration bereitstellen (z. B. Result::unwrap), aber unter der Haube werden sie immer mit einer match implementiert.

Wenn Sie wissen, dass ein besonderer Fall in einem match nicht erreichbar ist, ist eine gängige Praxis unreachable!() auf diesem Zweig zu schreiben (unreachable!() einfach erweitert auf ein panic!() mit einer bestimmten Nachricht).


Wenn Sie nur eine ENUM mit einer Variante haben, können Sie auch eine einfache let Anweisung schreiben die Enum dekonstruieren. Muster in let Aussagen müssen erschöpfend sein, und ein Muster, das die einzelne Variante von einem enum abgleicht, ist erschöpfend. Aber Enums mit nur einer Variante werden so gut wie nie benutzt; Eine Struktur würde den Job gut machen. Und wenn Sie später Varianten hinzufügen möchten, schreiben Sie besser sofort eine match.

enum Single { 
    S(i32), 
} 

fn main() { 
    let a = Single::S(1); 
    let Single::S(b) = a; 
    println!("{}", b); 
} 

Auf der anderen Seite, wenn Sie eine Enumeration mit mehr als einer Variante haben, können Sie auch if let und while let verwenden, wenn Sie nur die Daten aus einer einzigen Variante interessiert sind. Während let ein erschöpfendes Muster erfordert, erfordern if let und while let ein nicht erschöpfendes Muster.

fn main() { 
    if let Some(x) = std::env::args().len().checked_add(1) { 
     println!("{}", x); 
    } else { 
     println!("too many args :("); 
    } 
} 
+0

Auch Sie werden oft sehen, wie sie mit Option verwendet Erwähnenswert ist vielleicht die Syntax ['if let'] (https://rustbyexample.com/flow_control/if_let.html) – user25064

+0

@ user25064 Guter Punkt! Aktualisiert. –