Gyakran hasznos, ha egy csomó elemet csoportosítunk, és az így kapott csoportokat egységként kezeljük. Rustban az ilyen csoportot struct-nak, az egyes elemeket pedig a struct egy-egy mezőjének nevezzük. A struct meghatározza a rendelkezésre álló mezők általános körét, a struct egy konkrét előfordulását viszont példánynak nevezzük.
Ráadásul a struct-okhoz metódusokat is definiálhatunk, amelyek hozzáférnek a mezőkhöz. Ilyenkor magára a structra self néven hivatkozunk. Amikor egy metódus &mut self-et használ, a mezők módosíthatók. Amikor egy metódus &self-et használ, a mezők nem módosíthatók: megváltoztathatatlanok. A módosíthatóság szabályozása segít a kölcsönzés-ellenőrzőnek abban, hogy bizonyos párhuzamossági hibacsoportok egyszerűen elő se fordulhassanak Rustban.
Ebben a feladatban kétféle metódust fogsz megvalósítani egy struct-on. Az elsőket általában gettereknek nevezik: hozzáférhetővé teszik a struct mezőit a külvilág számára, anélkül hogy bárki más módosíthatná az értéküket. Rustban ezek a metódusok szokás szerint ugyanazt a nevet kapják, mint a mező, amelyet hozzáférhetővé tesznek. Ha például van egy getter metódusunk, amely egy name nevű mezőt kér le, akkor a metódus egyszerűen a name() nevet kapja.
Egy másik fajta metódust is meg fogsz valósítani, ezeket általában settereknek nevezik. Ezek megváltoztatják a mező értékét. A setterek nem túl gyakoriak Rustban: ha egy mezőt szabadon lehet módosítani, akkor inkább egyszerűen publikussá tesszük. Akkor viszont hasznosak, ha a mező frissítésének mellékhatása kell legyen, vagy hozzáférés-szabályozáshoz: egy pub(crate) jelölésű setter lehetővé teszi, hogy ugyanazon crate más moduljai is frissítsenek egy privát mezőt, amelyre a külvilág nem hathat.
A struct-oknak három fajtája van: a nevesített mezőkkel rendelkező struct-ok, a tuple struct-ok és a unit struct-ok. Ebben a tanulófeladatban az első változatot járjuk körül: a nevesített mezőkkel rendelkező struct-okat.
A struct-okat a struct kulcsszóval definiáljuk, amelyet a leírt típus nagy kezdőbetűs neve követ:
struct Item {}
Ezután további típusokat viszünk be a struct testébe a struct mezőiként, mindegyiket a saját típusával:
struct Item {
name: String,
weight: f32,
worth: u32,
}
Végül a struct-okon impl blokkon belül definiálhatunk metódusokat:
impl Item {
// initializes and returns a new instance of our Item struct
fn new() -> Self {
todo!()
}
}
Most, hogy ezzel röviden áttekintettük a struct-ok szintaxisát, vess egy pillantást a feladat utasításaira!
Egy egészségfigyelő rendszer megvalósításán dolgozol. Ennek részeként nyomon kell követned a felhasználók egészségügyi statisztikáit.
Kiindulásként néhány csonkolt függvényt találsz egy impl blokkban, valamint az alábbi struct definíciót:
pub struct User {
name: String,
age: u32,
weight: f32,
}
A célod, hogy megvalósítsd a User struct csonkolt metódusait, amelyeket az impl blokkban definiáltunk.
A new metódus például a megadott névvel, életkorral és súllyal rendelkező User példányt ad vissza.
let mut bob = User::new(String::from("Bob"), 32, 155.2);
// Returns: a User with name "Bob", age 32, and weight 155.2
A weight metódus a User súlyát adja vissza.
bob.weight();
// Returns: 155.2
A set_age metódus beállítja a User életkorát.
bob.set_age(33);
// Updates Bob's age to 33; happy birthday Bob!
Jó szórakozást!
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Rust nyelvet 99 feladat segítségével, valódi emberi mentorálással, mindez ingyen.