Minska din rostkodsfotavtryck och öka dess robusthet med generiska typer.

Det finns alltid nivåer av osäkerhet när man utvecklar applikationer, vilket kan leda till fel, speciellt om dina funktioner accepterar specifika typer av argument. För att minska fel på grund av osäkerheter kan du använda Generics. Generics tillhandahåller funktionalitet för att skapa klasser, funktioner och datastrukturer för att arbeta med olika typer.

Med hjälp av generika kan du skapa och definiera algoritmer och datastrukturer som kan fungera på flera typer utan att skriva komplex kod och separata implementeringar för varje typ. Generika förbättrar kodåteranvändbarhet och effektivitet samtidigt som typsäkerhet och prestanda bibehålls.

Använder generiska typer i rost

Rusts generiska typ kan samverka med andra typer av rostdata. Du kommer att definiera generiska typer med vinkelparenteser (<>), följt av två eller flera parametrar.

Här är en generisk strukturdefinition som kräver två generiska typparametrar:

strukturPunkt
 {
// T och U är generiska typparametrar som x- och y-fälten kommer att göra
// anta vid instansiering
x: T,
y: U,
}

I den Punkt struktur, T, och U är generiska typparametrar.

Du kan ersätta de generiska typparametrarna med valfri datatyp vid instansiering:

fnhuvud() {
låta min_punkt = Punkt { x: Sträng::från("Hallå"), y: Sträng::från("värld") };

println!(
"X-värdet för min_punkt är {} och y-värdet är {}.",
min_punkt.x,
min_punkt.y
);
}

De min poäng variabel är en instans av Punkt struct initierad med strängtyper. Rust-kompilatorn härleder konkreta typer av T och U baserat på värdena på instansiering.

Egenskapsgränser för generiska typer

Generiska rosttyper kan använda egenskapsgränser för att säkerställa typsäkerhet. Egenskaper är samlingar av metoder som typer kan implementera för att uppvisa vissa beteenden definierade för egenskapen.

Egenskapsgränser anger att en generisk typ måste implementera en eller flera egenskaper.

Här är ett exempel på en generisk funktion som returnerar det största av två värden med en egenskapsbunden som säkerställer att de jämförda typerna implementerar egenskapen:

// Maximum är en egenskap som definierar en metod för att utvärdera maximalt två
// typer
dragMaximal {
fnmax(själv, Övrig: Själv) -> Själv;
}

// Implementerar egenskapen "Maximum" för alla typer som implementerar
// 'PartialOrd'-egenskap.
implPartialOrd> Max för T {
fnmax(själv, Övrig: Själv) -> Själv {
// returnera `self` om det är större än `other`; annars, återvända
// `annat.`
omsjälv > andra {
själv
} annan {
Övrig
}
}
}

fnhuvud() {
låta a = 5;
låta b = 10;
låta största = Maximum:: max (a, b);
println!("Det största värdet är {}", största);
}

De Maximal egenskap har en max metod som returnerar det största av två värden av samma typ. Alla typer som implementerar PartialOrd egenskap implementerar Maximal drag.

De max metoden tar två värden av Själv typ – hänvisar till typen som implementerar Maximal egenskap — och jämför värdena.

De huvud funktion jämför två variabler med hjälp av max metod och trycker den största.

Begränsningar för generiska typer

Begränsningar liknar egenskapsgränser, men de låter dig ange ytterligare krav på typer du använder som typparametrar.

Om du vill skapa en generisk funktion som accepterar typer för strängkonvertering, kan du använda en begränsning för att säkerställa att typparametern implementerar en egenskap.

// ToString är en egenskap med en strängkonverteringsmetod
dragAtt stränga {
fnatt stränga(&själv) -> Sträng;
}

// to_string är en generisk funktion som tar ett värde av vilken typ som helst som
// implementerar ToString-egenskapen
fnatt strängaAtt stränga>(värde: T) -> Sträng {
value.to_string()
}

De att stränga värdeparametern måste implementera Att stränga egenskap, vilket säkerställer att du kan konvertera värden av typ T att stränga med att stränga metod.

Generiska typer är användbara för att arbeta med egenskaper

Generiska rosttyper är kraftfulla och det finns områden att förbättra. Ett kritiskt fokusområde är att förbättra prestanda för generisk kod. För närvarande kan Rusts typsystem lägga överkostnader på generisk kod, vilket saktar ner prestandan.

Generiska typer är fördelaktiga för att arbeta med egenskaper. Med hjälp av generiska typer kan du skapa egenskapsobjekt som fungerar med vilken typ som helst som implementerar en egenskap för att göra dina metoder mer flexibla.