At lære om disse to koncepter vil hjælpe med at styrke din forståelse af, hvordan Rust fungerer, og hvordan du kan implementere OOP-funktioner.

Egenskaber og levetider er nøglekomponenter i Rust. Du kan bruge egenskaber til at definere adfærd og muligheder for typer, der skal implementeres. De er meget alsidige, så du kan skrive mere generisk kode, reducere duplikering og forbedre vedligeholdelsen.

Rust bruger en anden mekanisme - levetider - til at spore ejerskab af variabler inden for og uden for omfanget. Dette forhindrer dinglende pointer under variabel deallokering.

Tilsammen hjælper egenskaber og levetider med at sikre typesikkerhed, hukommelsessikkerhed og kodepålidelighed.

Forståelse af træk i rust

Træk er samlinger af metoder, som andre typer kan implementere. Egenskaber ligner grænseflader på sprog som Java, Go og TypeScript, men mere fleksible.

Du vil bruge egenskab nøgleord til at definere træk i Rust, efterfulgt af en erklæring om metodesignaturer.

egenskabMyTrait {
fnmin_metode(&selv);
}
instagram viewer

Koden definerer en egenskab ved navn MyTrait med en min_metode metode. Det &selv parameter angiver, at metoden refererer til objektet for implementeringstypen som dens første parameter.

Efter at have defineret en egenskab, kan du implementere den til dine tilpassede typer.

Her er, hvordan du kan implementere en egenskab for dine strukturtyper.

strukturPerson {
navn: Snor,
alder: u32,
}

impl Info til Person {
fnResumé(&selv) {
println!("Mit navn er {} og jeg er {} år gammel.", selv.navn, selv.alder);
}
}

Det Person strukturere redskaber Info, og du kan ringe til Resumé metode på forekomster af Person struktur.

fnvigtigste(){
lade john = Person {navn: Snor::fra("John"), alder: 30 };
john.resumé(); // Output: Jeg hedder John, og jeg er 30 år gammel.
}

Det John variabel er en forekomst af Person struktur.

Det vigtigste funktionskald Resumé som udskriver en besked til konsollen:

Enums kan implementere egenskaber. Her er, hvordan du kan definere en enum med varianter, der implementerer Resumé metode:

enumMyEnum {
Variant A,
VariantB,
}

impl Info til MyEnum {
fnResumé(&selv) {
matchselv {
MyEnum:: VariantA => {
// implementering for VariantA
}
MyEnum:: VariantB => {
// implementering for VariantB
}
}
}
}

Brug af egenskaber til funktionsparametre og returværdier

Du kan bruge egenskaber som funktionsparametre og returværdier. Brug af egenskaber som funktionsparametre er praktisk til at skrive generisk kode med flere typer.

Her er en funktion, der tager en parameter af enhver type, der implementerer Info.

fngør noget(værdi: T) {
værdi.sammendrag();
}

Det syntaks angiver det T skal gennemføre Info. Du kan ringe til Resumé funktion med enhver værdi, der implementerer Info.

Levetider i Rust

Rusts lånetjekværktøj analyserer programmer og sikrer korrekt hukommelsesforbrug. I Rust, hver værdi har en ejer der er ansvarlig for at tildele værdien. Hvornår variable låneværdier, låner de en reference til den beståede værdi, men ejeren bevarer ejerskabet.

Levetider er en måde at sikre, at lånte værdier bruges korrekt. En levetid er en etiket knyttet til en reference, der beskriver, hvor længe referencen er gyldig.

I Rust kan du angive en levetid ved hjælp af en apostrof-anmærkning:

func<'en>

Ved oprettelse af en reference tildeles referencen en levetid, der beskriver, hvor længe den er gyldig. Hvis du har en funktion, der tager referencen til en værdi, skal levetiden være længere end funktionskaldet for at sikre, at værdien er gyldig, når funktionen vender tilbage.

Her er et eksempel på levetidsspecifikation i en funktion.

fngør noget<'en>(x: &'eni32) -> &'eni32 {
x
}

fnvigtigste() {
lade x = 42;
lade resultat = gør_noget(&x);
println!("Resultatet er: {}", resultat);
}

I den gør noget funktion, den 'en levetidsparameter angiver, at referencen til x er gyldig så længe funktionskaldet. Den returnerede reference er også gyldig, så længe funktionskaldet.

Det vigtigste funktion udskriver resultatet ved at sende en reference til x variabel i vigtigste funktion til konsollen.

Livstidssyntaksen kan være udførlig, men den er afgørende for sikkerhed og hukommelsesstyring. Elisionsregler for tre levetider giver retningslinjer, der tillader Rust at udlede referencernes levetid i visse situationer.

Input levetidsreglen

Input-levetidsreglen angiver, at hvis en funktion eller metode tager en eller flere referencer som inputparametre, antager Rust, at alle referencer har samme levetid.

Enkelt sagt vil levetiden for outputreferencer være den samme som for inputreferencerne.

fnlængst<'en>(x: &'enstr, y: &'enstr) -> &'enstr {
hvis x.len() > y.len() { x } andet {y}
}

I den længst funktion, Rust udleder, at levetiden for outputreferencen er den samme som inputreferencen, fordi de begge har samme levetidsparameter 'en.

Input-levetidsreglen gør det nemt at skrive generiske funktioner, der tager flere referencer som input.

Output Lifetime-reglen

Output-levetidsreglen angiver, at hvis en funktion eller metode returnerer en reference, vil Rust antage, at levetiden for output-referencen er forskellig fra levetiden for enhver inputreference.

fnførste_ord<'en>(s: &'enstr) -> &'enstr {
s.split_whitespace().next().unwrap()
}

I denne funktion udleder Rust, at levetiden for outputreferencen er forskellig fra levetiden for inputreferencen, fordi split_whitespace() metoden opretter en output-reference, der ikke tager nogen input-referenceparametre.

Elision of Lifetimes Regel

Elision of lifetimes-reglen gælder, hvis en funktion eller metode tager én reference eller inputparameter og returnerer en reference. I så fald antager Rust, at outputreferencen har samme levetid som inputreferencen.

fnlængst<'en>(x: &'enstr, y: &str) -> &'enstr {
hvis x.len() > y.len() { x } andet {y}
}

I denne funktion udleder Rust, at levetiden for outputreferencen er den samme som levetiden for inputreferencen, fordi inputreferencen y har ingen levetidsparameter. Rust elider levetidsparameteren for y og antager, at den har samme levetid som x.

Denne regel gør det lettere at skrive funktioner, der tager én inputreference og returnerer én outputreference.

Træk og levetider

Du kan kombinere egenskaber og levetider for at skabe generiske funktioner, der fungerer for typer, der implementerer en egenskab og har en gyldig levetid.

Her er et træk og en funktion, der refererer til en værdi, der implementerer træk.

egenskabToString {
fntil_streng(&selv) -> Snor;
}

fntil_streng<'en, T: ToString>(t: &'en T) -> Snor {
t.to_string()
}

Her er levetidsparameteren 'en sikrer, at referencen t er gyldig i hele levetiden af ​​det objekt, det refererer til. Du kan bruge til_streng funktion med typer, der implementerer ToString egenskab med en gyldig levetid.

Træk danner grundlaget for implementering af OOP-koncepter i rust

Træk sætter dig i stand til at definere adfærd. Selvom Rust ikke er et objektorienteret programmeringssprog (OOP), kan du bruge træk til at implementere OOP-koncepter fra indkapsling til nedarvning, polymorfi og abstraktion.

Implementering af disse OOP-koncepter med egenskaber gør dine Rust-programmer skalerbare, robuste, vedligeholdelige og effektive.