Iterieren über Ergebnisse

RustRustBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab untersuchen wir verschiedene Strategien, um die Möglichkeit von Fehlern zu behandeln, während wir über eine Sammlung von Results in Rust iterieren.

Hinweis: Wenn das Lab keinen Dateinamen angibt, können Sie einen beliebigen Dateinamen verwenden. Beispielsweise können Sie main.rs verwenden und es mit rustc main.rs &&./main kompilieren und ausführen.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/BasicConceptsGroup -.-> rust/mutable_variables("Mutable Variables") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/mutable_variables -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/integer_types -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/string_type -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/function_syntax -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/expressions_statements -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/method_syntax -.-> lab-99251{{"Iterieren über Ergebnisse"}} rust/operator_overloading -.-> lab-99251{{"Iterieren über Ergebnisse"}} end

Iterieren über Results

Eine Iter::map-Operation kann fehlschlagen, z.B.:

fn main() {
    let strings = vec!["tofu", "93", "18"];
    let numbers: Vec<_> = strings
     .into_iter()
     .map(|s| s.parse::<i32>())
     .collect();
    println!("Results: {:?}", numbers);
}

Schauen wir uns die Strategien an, um dies zu behandeln.

Ignorieren Sie die fehlgeschlagenen Elemente mit filter_map()

filter_map ruft eine Funktion auf und filtert die Ergebnisse, die None sind.

fn main() {
    let strings = vec!["tofu", "93", "18"];
    let numbers: Vec<_> = strings
     .into_iter()
     .filter_map(|s| s.parse::<i32>().ok())
     .collect();
    println!("Results: {:?}", numbers);
}

Sammeln Sie die fehlgeschlagenen Elemente mit map_err() und filter_map()

map_err ruft eine Funktion mit dem Fehler auf, so dass wir sie, indem wir sie der vorherigen filter_map-Lösung hinzufügen, während des Iterierens beiseite legen können.

fn main() {
    let strings = vec!["42", "tofu", "93", "999", "18"];
    let mut errors = vec![];
    let numbers: Vec<_> = strings
     .into_iter()
     .map(|s| s.parse::<u8>())
     .filter_map(|r| r.map_err(|e| errors.push(e)).ok())
     .collect();
    println!("Numbers: {:?}", numbers);
    println!("Errors: {:?}", errors);
}

Den gesamten Vorgang mit collect() abbrechen

Result implementiert FromIterator, sodass ein Vektor von Ergebnissen (Vec<Result<T, E>>) in ein Ergebnis mit einem Vektor (Result<Vec<T>, E>) umgewandelt werden kann. Sobald ein Result::Err gefunden wird, wird die Iteration abgebrochen.

fn main() {
    let strings = vec!["tofu", "93", "18"];
    let numbers: Result<Vec<_>, _> = strings
     .into_iter()
     .map(|s| s.parse::<i32>())
     .collect();
    println!("Results: {:?}", numbers);
}

Dieselbe Technik kann mit Option verwendet werden.

Sammeln Sie alle gültigen Werte und Fehler mit partition()

fn main() {
    let strings = vec!["tofu", "93", "18"];
    let (numbers, errors): (Vec<_>, Vec<_>) = strings
     .into_iter()
     .map(|s| s.parse::<i32>())
     .partition(Result::is_ok);
    println!("Numbers: {:?}", numbers);
    println!("Errors: {:?}", errors);
}

Wenn Sie sich die Ergebnisse ansehen, werden Sie feststellen, dass alles immer noch in Result eingeschlossen ist. Dafür ist ein bisschen mehr Boilerplate erforderlich.

fn main() {
    let strings = vec!["tofu", "93", "18"];
    let (numbers, errors): (Vec<_>, Vec<_>) = strings
     .into_iter()
     .map(|s| s.parse::<i32>())
     .partition(Result::is_ok);
    let numbers: Vec<_> = numbers.into_iter().map(Result::unwrap).collect();
    let errors: Vec<_> = errors.into_iter().map(Result::unwrap_err).collect();
    println!("Numbers: {:?}", numbers);
    println!("Errors: {:?}", errors);
}

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Lab Iterieren über Results abgeschlossen. Sie können in LabEx weitere Labs ausprobieren, um Ihre Fähigkeiten zu verbessern.