Reduzieren Sie Ihren Rust-Code-Fußabdruck und erhöhen Sie seine Robustheit mit generischen Typen.

Bei der Entwicklung von Anwendungen gibt es immer Unsicherheiten, die zu Fehlern führen können, insbesondere wenn Ihre Funktionen bestimmte Arten von Argumenten akzeptieren. Um Fehler aufgrund von Unsicherheiten zu reduzieren, können Sie Generics verwenden. Generics bieten Funktionen zum Erstellen von Klassen, Funktionen und Datenstrukturen für die Arbeit mit verschiedenen Typen.

Mithilfe von Generika können Sie Algorithmen und Datenstrukturen erstellen und definieren, die auf mehreren Typen ausgeführt werden können, ohne komplexen Code und separate Implementierungen für jeden Typ schreiben zu müssen. Generics verbessern die Wiederverwendbarkeit und Effizienz von Code, während Typsicherheit und Leistung erhalten bleiben.

Generische Typen in Rust verwenden

Der generische Typ von Rust kann mit interagieren andere Rust-Datentypen. Sie definieren generische Typen mit spitzen Klammern (<>), gefolgt von zwei oder mehr Parametern.

instagram viewer

Hier ist ein Generikum Strukturdefinition das nimmt zwei generische Typparameter:

StrukturPunkt {
// T und U sind generische Typparameter, die die x- und y-Felder verwenden
// bei Instanziierung annehmen
x: T,
y: U,
}

Im Punkt Struktur, T, Und U sind generische Typparameter.

Sie können die generischen Typparameter bei der Instanziierung durch jeden Datentyp ersetzen:

fnhauptsächlich() {
lassen my_point = Punkt { x: Schnur::aus("Hallo"), ja: Schnur::aus("Welt") };

drucken!(
"Der x-Wert von my_point ist {} und der y-Wert ist {}.",
mein_punkt.x,
mein_punkt.y
);
}

Der mein Punkt Variable ist eine Instanz von Punkt struct mit String-Typen initialisiert. Der Rust-Compiler leitet die konkreten Typen von ab T Und U basierend auf den Werten bei der Instanziierung.

Eigenschaftsgrenzen für generische Typen

Generische Rust-Typen können Merkmalsgrenzen verwenden, um Typsicherheit zu gewährleisten. Eigenschaften sind Sammlungen von Methoden, die Typen implementieren können, um bestimmte Verhaltensweisen zu zeigen, die für die Eigenschaft definiert sind.

Eigenschaftsgrenzen geben an, dass ein generischer Typ eine oder mehrere Eigenschaften implementieren muss.

Hier ist ein Beispiel für eine generische Funktion, die den größeren von zwei Werten mit einer Eigenschaftsgrenze zurückgibt, die sicherstellt, dass die verglichenen Typen die Eigenschaft implementieren:

// Maximum ist eine Eigenschaft, die eine Methode zum Bewerten des Maximums von zwei definiert
// Typen
MerkmalMaximal {
fnmax(selbst, andere: Selbst) -> Selbst;
}

// Implementiert das `Maximum`-Merkmal für alle Typen, die das implementieren
// `PartialOrd`-Eigenschaft.
implTeilOrd> Maximal für T {
fnmax(selbst, andere: Selbst) -> Selbst {
// `self` zurückgeben, wenn es größer als `other` ist; ansonsten zurück
// `Andere.`
Wennselbst > andere {
selbst
} anders {
andere
}
}
}

fnhauptsächlich() {
lassen ein = 5;
lassen b = 10;
lassen größte = Maximum:: max (a, b);
drucken!("Der größte Wert ist {}", größten);
}

Der Maximal Eigenschaft hat a max Methode, die den größeren von zwei Werten desselben Typs zurückgibt. Jeder Typ, der die implementiert TeilOrd Merkmal implementiert die Maximal Merkmal.

Der max Methode nimmt zwei Werte der Selbst Typ – bezieht sich auf den Typ, der die implementiert Maximal Merkmal – und vergleicht die Werte.

Der hauptsächlich Funktion vergleicht zwei Variablen mit der max Methode und druckt am größten.

Einschränkungen für generische Typen

Einschränkungen ähneln Eigenschaftsgrenzen, aber sie ermöglichen es Ihnen, zusätzliche Anforderungen an Typen anzugeben, die Sie als Typparameter verwenden.

Wenn Sie eine generische Funktion erstellen möchten, die Typen für die Zeichenfolgenkonvertierung akzeptiert, können Sie eine Einschränkung verwenden, um sicherzustellen, dass der Typparameter eine Eigenschaft implementiert.

// ToString ist ein Trait mit einer String-Konvertierungsmethode
MerkmalToString {
fnto_string(&selbst) -> Schnur;
}

// to_string ist eine generische Funktion, die einen beliebigen Wert akzeptiert
// implementiert das ToString-Merkmal
fnto_stringToString>(Wert: T) -> Schnur {
value.to_string()
}

Der to_string value Parameter muss die implementieren ToString -Eigenschaft, die sicherstellt, dass Sie Werte vom Typ konvertieren können T mit dem zu besaiten to_string Methode.

Generische Typen sind nützlich für die Arbeit mit Merkmalen

Rust-generische Typen sind leistungsfähig und es gibt Bereiche für Verbesserungen. Ein kritischer Schwerpunkt liegt auf der Verbesserung der Leistung von generischem Code. Derzeit kann das Typsystem von Rust generischen Code überlasten und die Leistung verlangsamen.

Generische Typen sind für die Arbeit mit Merkmalen von Vorteil. Mit generischen Typen können Sie Eigenschaftsobjekte erstellen, die mit jedem Typ funktionieren, der eine Eigenschaft implementiert, um Ihre Methoden flexibler zu machen.