Rust-Fehlerbehandlung mit Fragezeichen

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 werden wir uns mit dem ?-Operator in Rust beschäftigen, der uns ermöglicht, die Fehlerbehandlung zu vereinfachen, indem wir Err zurückgeben anstatt zu panic zu greifen. Wir werden auch die try!-Makro untersuchen, das ähnliche Funktionalität hatte, bevor ? eingeführt wurde.

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/DataTypesGroup(["Data Types"]) rust(("Rust")) -.-> rust/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/ErrorHandlingandDebuggingGroup(["Error Handling and Debugging"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust(("Rust")) -.-> rust/BasicConceptsGroup(["Basic Concepts"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") 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/ErrorHandlingandDebuggingGroup -.-> rust/error_propagation("Error Propagation") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} rust/integer_types -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} rust/string_type -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} rust/function_syntax -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} rust/expressions_statements -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} rust/error_propagation -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} rust/operator_overloading -.-> lab-99243{{"Rust-Fehlerbehandlung mit Fragezeichen"}} end

Einführung des ?

Manchmal möchten wir einfach die Einfachheit von unwrap ohne die Möglichkeit eines panic. Bislang hat unwrap uns gezwungen, immer tiefer zu verschachteln, wenn wir eigentlich nur die Variable herausholen wollten. Dies ist genau der Zweck von ?.

Wenn ein Err gefunden wird, gibt es zwei gültige Aktionen:

  1. panic!, das wir bereits entschieden haben, möglichst zu vermeiden
  2. return, da ein Err bedeutet, dass es nicht behandelt werden kann

? ist fast[^†] genau gleichwertig zu einem unwrap, das return statt panic bei Errs aufruft. Schauen wir uns an, wie wir das frühere Beispiel, das Kombinatoren verwendete, vereinfachen können:

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = first_number_str.parse::<i32>()?;
    let second_number = second_number_str.parse::<i32>()?;

    Ok(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() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

Das try!-Makro

Bevor ? existierte, wurde die gleiche Funktionalität mit dem try!-Makro erreicht. Der ?-Operator wird jetzt empfohlen, aber Sie werden ihn möglicherweise immer noch in älterem Code finden. Die gleiche multiply-Funktion aus dem vorherigen Beispiel würde mit try! so aussehen:

// Um dieses Beispiel ohne Fehler zu kompilieren und auszuführen, während Sie Cargo verwenden, ändern Sie den Wert
// des `edition`-Felds im `[package]`-Abschnitt der `Cargo.toml`-Datei in "2015".

use std::num::ParseIntError;

fn multiply(first_number_str: &str, second_number_str: &str) -> Result<i32, ParseIntError> {
    let first_number = try!(first_number_str.parse::<i32>());
    let second_number = try!(second_number_str.parse::<i32>());

    Ok(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() {
    print(multiply("10", "2"));
    print(multiply("t", "2"));
}

Zusammenfassung

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