Először nevezd meg, mire van szükséged
Ha a Rust fordítója megállít, könnyű minden függvényhívás elé egy clone()-t írni. Ezzel néhány hiba valóban eltűnik, de az adat életútja homályos marad. Tegyél fel inkább három kérdést: a fogadó kódnak saját példány kell, csak olvasnia kell, vagy módosítania kell az eredetit? A válasz a függvény aláírásában is megjelenhet.
Az alábbi példák egy névjegyzékből indulnak ki. A szöveg a hívóé; az ellenőrző függvénynek nincs oka elvenni vagy megtartani. A fogalmak hátterét az ownership és move leckében, a referenciákat a kölcsönzés leckében találod. Itt a konkrét hibajavításra koncentrálunk.
E0382: átadtad a tulajdont, majd újra használnád
A következő program szándékosan hibás. A kiir egy String értéket vesz át. A hívás után a nev változót mégis újra kiírnánk. Ezt jelzi az E0382 hiba magyarázata.
fn kiir(nev: String) { println!("{nev}"); }
fn main() {
let nev = String::from("Réka");
kiir(nev);
println!("{nev}");
}
Ha csak olvasásra van szükség, a függvény kérjen &str értéket. A hívó kölcsönadja a szöveget, a hívás után pedig tovább használhatja. Ez az első javítás. A második lehetőség a tulajdon szándékos átadása: akkor a későbbi használatot kell megszüntetni vagy a függvényből visszaadni az értéket. A harmadik az önálló másolat, ha a két példány valóban külön életet él. Stringnél a klónozás ekkor indokolt lehet, de a szükségletet érdemes előbb megnevezni.
fn kiir(nev: &str) { println!("{nev}"); }
fn main() {
let nev = String::from("Réka");
kiir(&nev);
assert_eq!(nev, "Réka");
}
E0502: ugyanazt az adatot olvasnád és módosítanád
Más helyzet, amikor nincs tulajdonosváltás, de egy élő referencia ütközik a módosítással. A következő programban az első elemre mutató referenciát a vektor bővítése után még használjuk. A bővítés megváltoztathatja a tárolást, ezért ez a két hozzáférés nem fér össze. Az E0502 leírása a kölcsönzések ütközését részletezi.
fn main() {
let mut nevek = vec![String::from("Réka")];
let elso = &nevek[0];
nevek.push(String::from("Áron"));
println!("{elso}");
}
Az első javítás a műveletek sorrendje: használd el a referenciát, és csak utána módosíts. A második lehetőség, hogy az elem adata helyett egy olcsón másolható eredményt tartasz meg, például a hosszát. A harmadik, ha tényleg a korábbi szöveg önálló pillanatképe kell, egy tudatos klón. Ezek nem felcserélhető trükkök: eltérő jelentésük van, amit a program céljához kell választani.
fn main() {
let mut nevek = vec![String::from("Réka")];
let elso = &nevek[0];
assert_eq!(elso, "Réka");
nevek.push(String::from("Áron"));
assert_eq!(nevek.len(), 2);
}
Javítási rutin, amely nagyobb programban is segít
Olvasd el a hibaüzenetben megjelölt első kölcsönzést és az utolsó használatot. Ne csak a pirosan jelzett sort nézd. Rajzold fel, melyik függvénynek kell saját adat, és melyiknek elég referencia. Ha egy mező hosszú ideig kölcsönzött, gyakran jobb kisebb lépésekre bontani a feldolgozást, mint mindent megosztott módosítható állapotba csomagolni.
A példák Rust 1.97.1, edition 2024 környezetre készültek. A kísérő ellenőrző a hibás blokkoknál az elvárt hibakódot, a jó blokkoknál a sikeres fordítást és futást vizsgálja. A referenciák hivatalos fejezete ad további példákat; a következő saját gyakorlatodban cseréld ki a neveket egy valódi doménadatra, és indokold meg minden klón szükségességét.
AI-val segített szerkesztőségi anyag. A technikai ellenőrzés környezetét a cikk végén jelezzük; emberi szakmai lektorálást ez a megjelölés nem állít.



