Rust von den Grundlagen bis zum Profi — Folge 5
Erstellen Sie wiederverwendbare APIs mit Generika, Merkmalen und Lebensdauern
Die in diesem Blog verfassten Artikel wurden mit dem Ziel erstellt, zu unterrichten. Außerdem können die Informationen im Artikel falsch sein, also seien Sie bitte vorsichtig.
Generische Elemente verwenden dieselben Regeln nur für verschiedene Typen wieder, und Merkmale definieren das Verhalten, das ein Typ bereitstellen muss. Lebenszeitnotationen beschreiben dem Compiler die Beziehungen zwischen Referenzen.
Verhalten mit Merkmalen definieren
trait Damageable {
fn is_alive(&self) -> bool;
fn take_damage(&mut self, amount: i32);
}
fn attack(target: &mut impl Damageable, damage: i32) {
if target.is_alive() {
target.take_damage(damage);
}
}
Attack kann einen Wert verwenden, der Damageable implementiert, ohne den konkreten Typ zu kennen. Ein Merkmal ähnelt eher einem Vertrag über erforderliches Verhalten als einer Vererbungshierarchie.
Generics und merkmalsgebunden
fn strongest<T>(values: &[T]) -> Option<&T>
where
T: Ord,
{
values.iter().max()
}
Da es eine Bedingung gibt, dass T Ord implementiert, weiß der Compiler, dass die Werte verglichen werden können. Ungültige Typkombinationen werden vor der Ausführung abgelehnt.
Implementierung von Merkmalen
struct Monster {
health: i32,
}
impl Damageable for Monster {
fn is_alive(&self) -> bool {
self.health > 0
}
fn take_damage(&mut self, amount: i32) {
self.health = (self.health - amount).max(0);
}
}
Durch die Trennung von Daten und gemeinsamen Verträgen können Merkmale in dem durch externe Typen zulässigen Umfang implementiert werden.
Lebensbeziehung
fn longer<'a>(a: &'a str, b: &'a str) -> &'a str {
if a.len() >= b.len() { a } else { b }
}
'a stellt die Beziehung dar, bei der die Rückgabereferenz die beiden Eingabereferenzen nicht überleben kann. Es handelt sich nicht um eine Funktion zur Verlängerung der tatsächlichen Lebensdauer einer Referenz oder zur Erstellung einer Laufzeitressource.
Die meisten einfachen Lebensdauern werden vom Compiler abgeleitet. Anstatt die Notation zu erhöhen, wenn ein Fehler auftritt, sollten Sie zunächst die Eigentumsbeziehung der API überprüfen, um zu sehen, welche Eingabe der Rückgabewert übernimmt.