Das Result-Enumeration in Rust erkunden

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 die Result-Enumeration in Rust, die uns ermöglicht, den Erfolg oder das Scheitern einer Operation auszudrücken, indem wir entweder Ok mit einem Wert oder Err mit einer Erklärung des Fehlers zurückgeben.

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/BasicConceptsGroup(["Basic Concepts"]) rust(("Rust")) -.-> rust/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/MemorySafetyandManagementGroup(["Memory Safety and Management"]) rust(("Rust")) -.-> rust/DataStructuresandEnumsGroup(["Data Structures and Enums"]) rust(("Rust")) -.-> rust/ErrorHandlingandDebuggingGroup(["Error Handling and Debugging"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") rust/DataTypesGroup -.-> rust/floating_types("Floating-point Types") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("Function Syntax") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("Expressions and Statements") rust/MemorySafetyandManagementGroup -.-> rust/lifetime_specifiers("Lifetime Specifiers") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/ErrorHandlingandDebuggingGroup -.-> rust/panic_usage("panic! Usage") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/floating_types -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/function_syntax -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/expressions_statements -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/lifetime_specifiers -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/method_syntax -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/panic_usage -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} rust/operator_overloading -.-> lab-99257{{"Das Result-Enumeration in Rust erkunden"}} end

Result

Wir haben gesehen, dass die Option-Enumeration als Rückgabewert von Funktionen verwendet werden kann, die fehlschlagen können, wobei None zurückgegeben werden kann, um ein Fehlerzustand anzuzeigen. Manchmal ist es jedoch wichtig, warum eine Operation fehlschlägt zu erklären. Dazu haben wir die Result-Enumeration.

Die Result<T, E>-Enumeration hat zwei Varianten:

  • Ok(value), was angibt, dass die Operation erfolgreich war, und umschließt den von der Operation zurückgegebenen value. (value hat den Typ T)
  • Err(why), was angibt, dass die Operation fehlgeschlagen ist, und umschließt why, das (hoffentlich) die Ursache des Fehlers erklärt. (why hat den Typ E)
mod checked {
    // Mathematische "Fehler", die wir fangen möchten
    #[derive(Debug)]
    pub enum MathError {
        DivisionByZero,
        NonPositiveLogarithm,
        NegativeSquareRoot,
    }

    pub type MathResult = Result<f64, MathError>;

    pub fn div(x: f64, y: f64) -> MathResult {
        if y == 0.0 {
            // Diese Operation würde `fehlschlagen`, stattdessen geben wir den Grund
            // des Fehlers in `Err` zurück
            Err(MathError::DivisionByZero)
        } else {
            // Diese Operation ist gültig, geben wir das Ergebnis in `Ok` zurück
            Ok(x / y)
        }
    }

    pub fn sqrt(x: f64) -> MathResult {
        if x < 0.0 {
            Err(MathError::NegativeSquareRoot)
        } else {
            Ok(x.sqrt())
        }
    }

    pub fn ln(x: f64) -> MathResult {
        if x <= 0.0 {
            Err(MathError::NonPositiveLogarithm)
        } else {
            Ok(x.ln())
        }
    }
}

// `op(x, y)` === `sqrt(ln(x / y))`
fn op(x: f64, y: f64) -> f64 {
    // Dies ist eine dreistufige Match-Pyramide!
    match checked::div(x, y) {
        Err(why) => panic!("{:?}", why),
        Ok(ratio) => match checked::ln(ratio) {
            Err(why) => panic!("{:?}", why),
            Ok(ln) => match checked::sqrt(ln) {
                Err(why) => panic!("{:?}", why),
                Ok(sqrt) => sqrt,
            },
        },
    }
}

fn main() {
    // Wird dies fehlschlagen?
    println!("{}", op(1.0, 10.0));
}

Zusammenfassung

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