Einführung
Bei echten Abfragen wird nicht immer ein Wert gefunden. Rust stellt diese Möglichkeit mit Option<T> dar: Some(value) bedeutet, dass ein Wert vorhanden ist, während None bedeutet, dass kein Wert vorhanden ist. Dadurch wird das Fehlen eines Werts Bestandteil des Typs, anstatt es hinter einer erfundenen Zahl zu verbergen oder eine Panik auszulösen.
Sie vervollständigen einen kleinen Inventarbericht, der vorhandene und fehlende Bestände behandelt, einen vorhandenen Datensatz mit null Bestand von einem fehlenden Datensatz unterscheidet und if let verwendet, wenn nur für den vorhandenen Fall eine Aktion erforderlich ist.
Vorhandene und fehlende Werte mit match unterscheiden
In diesem Schritt ersetzen Sie einen Platzhalterbericht durch ein vollständiges match über das optionale Ergebnis einer Abfrage.
Wechseln Sie in das vorbereitete Cargo-Projekt:
cd /home/labex/project/option-inventory
Öffnen Sie den Quellcode:
nano src/main.rs
Die vorbereitete Funktion find_stock gibt Option<u32> zurück. Lesen Sie die spitzen Klammern zunächst als „ein Option, das möglicherweise ein u32 enthält“; das Definieren wiederverwendbarer Typen mit Parametern in spitzen Klammern lernen Sie später. Some(12) enthält eine Bestandsanzahl, während None überhaupt keine Anzahl enthält.
Am Ende der vorbereiteten Abfrage verwendet _ => None das Wildcard-Muster _. Es bedeutet „jeder Wert, der von keinem vorherigen Arm erfasst wurde“. Das Wildcard-Muster erstellt keine verwendbare Variable. Es ignoriert den nicht passenden Wert absichtlich und gibt None zurück.
Suchen Sie das Platzhalter-println! innerhalb von report und ersetzen Sie diese eine Zeile durch das folgende match:
match find_stock(code) {
Some(count) => println!("{code}: {count} in stock"),
None => println!("{code}: not found"),
}
Some(count) erkennt nicht nur einen vorhandenen Wert, sondern gibt dessen innere Zahl auch unter dem lokalen Namen count verfügbar. Der Arm None behandelt das Fehlen ausdrücklich. Damit deckt das match jeden möglichen Wert von Option<u32> ab.
Speichern Sie mit Ctrl+O, drücken Sie Enter und beenden Sie den Editor mit Ctrl+X. Prüfen Sie das Programm, bevor Sie es ausführen:
cargo check
Finished bestätigt, dass beide Fälle von Option abgedeckt sind. Führen Sie den Bericht nun aus:
cargo run --quiet
Sie sollten Folgendes sehen:
A1: 12 in stock
B2: 0 in stock
Z9: not found
Die letzte Zeile stammt aus None; die ersten beiden stammen aus Some, einschließlich des Werts Some(0).
Nullbestand von fehlendem Bestand unterscheiden
In diesem Schritt geben Sie einem vorhandenen Datensatz mit null Bestand ein eigenes Verhalten, anstatt null als fehlenden Bestand zu behandeln.
Some(0) und None bedeuten unterschiedliche Dinge. Some(0) sagt aus, dass die Abfrage einen Datensatz gefunden hat, dessen Bestand null ist. None sagt aus, dass für diesen Code kein Datensatz existiert. Diese Unterscheidung zeigt, warum ein Platzhalter wie 0 kein sicherer Ersatz für das Fehlen eines Werts ist.
Öffnen Sie den Quellcode erneut:
nano src/main.rs
Fügen Sie innerhalb des match in report den folgenden Arm direkt über dem vorhandenen Arm Some(count) ein:
Some(0) => println!("{code}: out of stock"),
Die match-Arme werden von oben nach unten geprüft. Das spezifische Muster Some(0) muss vor Some(count) stehen, weil das allgemeinere Muster ebenfalls null akzeptiert.
Speichern und beenden Sie den Editor. Führen Sie anschließend das Programm aus:
cargo run --quiet
Die Ausgabe sollte nun so aussehen:
A1: 12 in stock
B2: out of stock
Z9: not found
Jede Zeile stellt jetzt einen eigenen Zustand dar: verfügbar, vorhanden, aber leer, oder fehlend.
Nur bei vorhandenem Wert eine Aktion ausführen
In diesem Schritt verwenden Sie if let für eine Aufgabe, die nur bei erfolgreicher Abfrage eine Aktion benötigt.
Ein vollständiges match eignet sich am besten, wenn jeder Fall ein anderes Verhalten benötigt. if let PATTERN = VALUE ist eine kompakte bedingte Musterprüfung für die andere häufige Situation: Führen Sie einen Block aus, wenn ein Muster passt, und tun Sie andernfalls nichts.
Öffnen Sie den Quellcode:
nano src/main.rs
Fügen Sie diese Funktion direkt über main ein:
fn highlight_available(code: &str) {
if let Some(count) = find_stock(code) {
println!("{code}: {count} available for promotion");
}
}
Das Muster ist nur bei Some erfolgreich. Daher ist count innerhalb der geschweiften Klammern verfügbar. Es gibt keinen else-Block, weil diese Hilfsfunktion absichtlich nichts für None ausgeben soll.
Entfernen Sie in main die führenden // aus der vorbereiteten Zeile highlight_available("C3");. Speichern und beenden Sie den Editor. Prüfen und starten Sie das Programm anschließend:
cargo check
cargo run --quiet
Die vollständige Ausgabe sollte so aussehen:
A1: 12 in stock
B2: out of stock
Z9: not found
C3: 5 available for promotion
Die vierte Zeile zeigt, dass if let den Wert innerhalb von Some(5) extrahiert hat, ohne für einen fehlenden Wert ein Verhalten zu erfinden.
Zusammenfassung
Sie haben Some und None unterschieden, den Unterschied zwischen Some(0) und dem Fehlen eines Werts beibehalten und if let verwendet, wenn nur für den vorhandenen Fall eine Aktion erforderlich war.


