Ce face struct
struct creează un tip propriu cu câmpuri numite. O valoare se construiește dând toate câmpurile: Elev { nume: ..., clasa: 10 }, iar câmpurile se citesc cu punct: elev.nume. Ca să modifici un câmp, toată variabila trebuie să fie mut; Rust nu are câmpuri mutabile individual.
Scurtături utile: dacă o variabilă are același nume ca un câmp, scrii doar Elev { nume, clasa }. Sintaxa ..alt ia restul câmpurilor dintr-o altă valoare. Metodele se adaugă separat, într-un bloc impl.
Există și tuple struct (struct Lei(f64);), cu câmpuri fără nume accesate cu .0, utile ca să faci tipuri distincte pentru aceeași reprezentare (lei vs. euro), și unit struct (struct Gol;), fără câmpuri. Afișarea cu {:?} cere #[derive(Debug)] deasupra structurii.
Exemple
Exemplul 1: Definire, creare și modificare
#[derive(Debug)] permite afișarea cu {:?} și {:#?}. Câmpul media se poate modifica doar pentru că ana este let mut. Elev { nume, ..ana.clone() } creează un elev nou cu alt nume și restul datelor copiate.
#[derive(Debug, Clone)]
struct Elev {
nume: String,
clasa: u8,
media: f64,
}
fn main() {
let mut ana = Elev { nume: String::from("Ana"), clasa: 10, media: 9.2 };
ana.media = 9.4;
println!("{} din clasa a {}-a are media {}", ana.nume, ana.clasa, ana.media);
let nume = String::from("Mihai");
let mihai = Elev { nume, ..ana.clone() };
println!("{mihai:?}");
println!("{ana:#?}");
}
Rezultat
Ana din clasa a 10-a are media 9.4
Elev { nume: "Mihai", clasa: 10, media: 9.4 }
Elev {
nume: "Ana",
clasa: 10,
media: 9.4,
}
Exemplul 2: Tuple struct și unit struct
Lei și Euro conțin amândouă un f64, dar sunt tipuri diferite: compilatorul nu te lasă să aduni lei cu euro din greșeală. Gratuit nu are date; contează doar tipul lui.
#[derive(Debug, Clone, Copy)]
struct Lei(f64);
struct Euro(f64);
struct Gratuit;
fn in_euro(suma: Lei) -> Euro {
Euro(suma.0 / 4.97)
}
fn cost_livrare(_: Gratuit) -> Lei {
Lei(0.0)
}
fn main() {
let pret = Lei(248.5);
println!("{:?} = {:.2} euro", pret, in_euro(pret).0);
println!("Livrare: {:?}", cost_livrare(Gratuit));
}
Rezultat
Lei(248.5) = 50.00 euro
Livrare: Lei(0.0)
Greșeli frecvente
- Încerci să faci un singur câmp mutabil (
mut media: f64în definiție). Nu există; mutabilitatea ține de variabilă:let mut elev = .... - Afișezi o structură cu
{:?}fără#[derive(Debug)]: eroarea`Elev` doesn't implement `Debug`. Pentru{}trebuie să implementezi singurDisplay. - Folosești
..altcu o structură care are câmpuriStringși apoi foloseștialt: câmpurile luate de acolo au fost mutate. Clonează (..alt.clone()) sau dă toate câmpurile cuString.
Comenzi înrudite
impl, self și Self: impl adaugă metode și funcții asociate unui tip; self este valoarea pe care se apelează metoda, iar Self este tipul însuși.enum: Definește un tip care poate fi exact una dintre mai multe variante; fiecare variantă poate avea propriile date.trait: Definește un set de metode pe care un tip promite să le aibă. Seamănă cu interfețele din alte limbaje și stă la baza generics.atribute (#[derive], #[cfg], #[allow]): Informații pentru compilator scrise cu #[…] deasupra unui element: generează cod (derive), aleg codul compilat (cfg) sau schimbă avertismentele.pattern matching (tipare): Tiparele descriu forma unei valori și scot din ea părțile de care ai nevoie: în let, match, if let, for și parametrii funcțiilor.