Rust Closures mit generischen Einschränkungen

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 wird erklärt, dass Closures in Rust die Typanonymität verwenden, was die Verwendung von Generics erfordert, wenn Closures als Funktionsparameter verwendet werden.

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/FunctionsandClosuresGroup(["Functions and Closures"]) rust(("Rust")) -.-> rust/AdvancedTopicsGroup(["Advanced Topics"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("Variable Declarations") 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-99325{{"Rust Closures mit generischen Einschränkungen"}} rust/function_syntax -.-> lab-99325{{"Rust Closures mit generischen Einschränkungen"}} rust/expressions_statements -.-> lab-99325{{"Rust Closures mit generischen Einschränkungen"}} rust/operator_overloading -.-> lab-99325{{"Rust Closures mit generischen Einschränkungen"}} end

Typanonymität

Closures fangen Variablen aus umgebenden Gültigkeitsbereichen präzise ein. Hat das irgendwelche Auswirkungen? Sicherlich. Betrachten Sie, wie die Verwendung eines Closures als Funktionsparameter [Generics] erfordert, was notwendig ist, aufgrund ihrer Definition:

// `F` muss generisch sein.
fn apply<F>(f: F) where
    F: FnOnce() {
    f();
}

Wenn ein Closure definiert wird, erstellt der Compiler implizit eine neue anonyme Struktur, um die eingefangenen Variablen darin zu speichern, und implementiert gleichzeitig die Funktionalität über einen der Traits: Fn, FnMut oder FnOnce für diesen unbekannten Typ. Dieser Typ wird der Variablen zugewiesen, die bis zum Aufruf gespeichert wird.

Da dieser neue Typ vom unbekannten Typ ist, erfordert jede Verwendung in einer Funktion Generics. Allerdings wäre ein unbeschränkter Typparameter <T> immer noch mehrdeutig und nicht erlaubt. Daher reicht die Begrenzung durch einen der Traits: Fn, FnMut oder FnOnce (den es implementiert), um seinen Typ anzugeben.

// `F` muss `Fn` implementieren für ein Closure, das keine
// Eingaben annimmt und nichts zurückgibt - genau das, was
// für `print` erforderlich ist.
fn apply<F>(f: F) where
    F: Fn() {
    f();
}

fn main() {
    let x = 7;

    // Fange `x` in einen anonymen Typ ein und implementiere
    // `Fn` für ihn. Speichere es in `print`.
    let print = || println!("{}", x);

    apply(print);
}

Zusammenfassung

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