Rust Generics Typenbeschrä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, wenn Sie mit Generics in Rust arbeiten, müssen die Typparameter durch Traits begrenzt werden, um die Funktionalität anzugeben, die ein Typ implementieren muss.

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/DataStructuresandEnumsGroup(["Data Structures and Enums"]) 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/DataStructuresandEnumsGroup -.-> rust/method_syntax("Method Syntax") rust/AdvancedTopicsGroup -.-> rust/traits("Traits") rust/AdvancedTopicsGroup -.-> rust/operator_overloading("Traits for Operator Overloading") subgraph Lab Skills rust/variable_declarations -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} rust/floating_types -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} rust/function_syntax -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} rust/expressions_statements -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} rust/method_syntax -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} rust/traits -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} rust/operator_overloading -.-> lab-99348{{"Rust Generics Typenbeschränkungen"}} end

Bounds

Wenn Sie mit Generics arbeiten, müssen die Typparameter oft Traits als Bounds verwenden, um festzulegen, welche Funktionalität ein Typ implementiert. Beispielsweise verwendet das folgende Beispiel das Display-Trait, um etwas auszugeben, und erfordert daher, dass T durch Display begrenzt ist; d.h. T muss Display implementieren.

// Definiert eine Funktion `printer`, die einen generischen Typ `T` annimmt,
// der das `Display`-Trait implementieren muss.
fn printer<T: Display>(t: T) {
    println!("{}", t);
}

Das Begrenzen beschränkt das Generic auf Typen, die den Bounds entsprechen. D.h.:

struct S<T: Display>(T);

// Fehler! `Vec<T>` implementiert `Display` nicht. Diese
// Spezialisierung wird fehlschlagen.
let s = S(vec![1]);

Ein weiterer Effekt des Begrenzens ist, dass generische Instanzen die [Methoden] der im Bound angegebenen Traits aufrufen können. Beispielsweise:

// Ein Trait, das das Druckmarker `{:?}` implementiert.
use std::fmt::Debug;

trait HasArea {
    fn area(&self) -> f64;
}

impl HasArea for Rectangle {
    fn area(&self) -> f64 { self.length * self.height }
}

#[derive(Debug)]
struct Rectangle { length: f64, height: f64 }
#[allow(dead_code)]
struct Triangle  { length: f64, height: f64 }

// Der generische Typ `T` muss `Debug` implementieren. Unabhängig
// vom Typ wird dies korrekt funktionieren.
fn print_debug<T: Debug>(t: &T) {
    println!("{:?}", t);
}

// `T` muss `HasArea` implementieren. Jeder Typ, der den
// Bound erfüllt, kann die `area`-Funktion von `HasArea` aufrufen.
fn area<T: HasArea>(t: &T) -> f64 { t.area() }

fn main() {
    let rectangle = Rectangle { length: 3.0, height: 4.0 };
    let _triangle = Triangle  { length: 3.0, height: 4.0 };

    print_debug(&rectangle);
    println!("Area: {}", area(&rectangle));

    //print_debug(&_triangle);
    //println!("Area: {}", area(&_triangle));
    // ^ TODO: Versuchen Sie, diese Zeilen zu aktivieren.
    // | Fehler: Implementiert weder `Debug` noch `HasArea`.
}

Als zusätzliche Bemerkung können where-Klauseln auch in einigen Fällen verwendet werden, um die Bounds ausdrücklicher anzuwenden.

Zusammenfassung

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