Map für Result

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, wie wir in Rust Kombinatoren wie map und and_then für den Result-Typ verwenden, um Fehler eleganter zu behandeln, wie in den bereitgestellten Beispielen gezeigt.

Hinweis: Wenn im Lab kein Dateiname angegeben ist, 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/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/integer_types("Integer Types") rust/DataTypesGroup -.-> rust/string_type("String Type") rust/DataTypesGroup -.-> rust/type_casting("Type Conversion and Casting") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99240{{"Map für Result"}} rust/integer_types -.-> lab-99240{{"Map für Result"}} rust/string_type -.-> lab-99240{{"Map für Result"}} rust/type_casting -.-> lab-99240{{"Map für Result"}} rust/function_syntax -.-> lab-99240{{"Map für Result"}} rust/expressions_statements -.-> lab-99240{{"Map für Result"}} rust/operator_overloading -.-> lab-99240{{"Map für Result"}} end

map für Result

Das Abfangen von Fehlern im vorherigen Beispiel in der multiply-Funktion macht den Code nicht robust. Im Allgemeinen möchten wir den Fehler an den Aufrufer zurückgeben, damit dieser entscheiden kann, wie er am besten auf den Fehler reagieren soll.

Wir müssen zunächst wissen, welchen Fehlertyp wir behandeln. Um den Err-Typ zu bestimmen, schauen wir uns parse() an, das mit dem FromStr-Trait für i32 implementiert ist. Folglich ist der Err-Typ als ParseIntError angegeben.

Im folgenden Beispiel führt der einfache match-Ausdruck zu einem insgesamt umständlicheren Code.

use std::num::ParseIntError;

// Nachdem der Rückgabetyp geändert wurde, verwenden wir die Mustermatching ohne `unwrap()`.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    match first_number_str.parse::<i32>() {
        Ok(first_number)  => {
            match second_number_str.parse::<i32>() {
                Ok(second_number)  => {
                    Ok(first_number * second_number)
                },
                Err(e) => Err(e),
            }
        },
        Err(e) => Err(e),
    }
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n ist {}", n),
        Err(e) => println!("Fehler: {}", e),
    }
}

fn main() {
    // Dies liefert immer noch eine vernünftige Antwort.
    let twenty = multiply("10", "2");
    print(twenty);

    // Dies liefert jetzt eine viel hilfreichere Fehlermeldung.
    let tt = multiply("t", "2");
    print(tt);
}

Zum Glück sind auch map, and_then und viele andere Kombinatoren von Option auch für Result implementiert. Result enthält eine vollständige Liste.

use std::num::ParseIntError;

// Wie bei `Option` können wir Kombinatoren wie `map()` verwenden.
// Diese Funktion ist ansonsten identisch zur obigen und lautet:
// Multipliziere, wenn beide Werte aus einem String geparst werden können, andernfalls übergebe den Fehler.
fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    first_number_str.parse::<i32>().and_then(|first_number| {
        second_number_str.parse::<i32>().map(|second_number| first_number * second_number)
    })
}

fn print(result: Result<i32, ParseIntError>) {
    match result {
        Ok(n)  => println!("n ist {}", n),
        Err(e) => println!("Fehler: {}", e),
    }
}

fn main() {
    // Dies liefert immer noch eine vernünftige Antwort.
    let twenty = multiply("10", "2");
    print(twenty);

    // Dies liefert jetzt eine viel hilfreichere Fehlermeldung.
    let tt = multiply("t", "2");
    print(tt);
}

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Lab zu Map für Result abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.