Ce face mem::replace
mem::replace(&mut loc, nou) scrie nou în loc și îți dă înapoi valoarea care era acolo. Este felul de a muta o valoare dintr-un câmp prin &mut self, lucru interzis direct (eroarea cannot move out of ... which is behind a mutable reference).
Dacă valoarea nouă este chiar valoarea implicită a tipului, mem::take este mai scurt.
Parametri
| Parametru | Descriere |
|---|---|
dest |
Locul modificat, prin &mut. |
src |
Valoarea nouă pusă în dest. |
Ce returnează
Valoarea veche din dest.
Exemple
Exemplul 1: Schimbarea stării unui automat
Starea veche este mutată afară ca să putem folosi datele din ea, iar în loc punem starea nouă.
use std::mem;
#[derive(Debug)]
enum Stare {
Cos(Vec<&'static str>),
Platita { produse: usize },
}
struct Comanda {
stare: Stare,
}
impl Comanda {
fn plateste(&mut self) {
let vechi = mem::replace(&mut self.stare, Stare::Platita { produse: 0 });
if let Stare::Cos(produse) = vechi {
println!("plătesc {} produse: {produse:?}", produse.len());
self.stare = Stare::Platita { produse: produse.len() };
}
}
}
fn main() {
let mut c = Comanda { stare: Stare::Cos(vec!["carte", "pix"]) };
println!("înainte: {:?}", c.stare);
c.plateste();
println!("după: {:?}", c.stare);
if let Stare::Platita { produse } = c.stare {
println!("produse plătite: {produse}");
}
}
Rezultat
înainte: Cos(["carte", "pix"])
plătesc 2 produse: ["carte", "pix"]
după: Platita { produse: 2 }
produse plătite: 2
Exemplul 2: Valoarea veche, înapoi
use std::mem;
fn main() {
let mut presedinte = String::from("Ion");
let fost = mem::replace(&mut presedinte, String::from("Maria"));
println!("fost: {fost}, acum: {presedinte}");
let mut scor = 87;
let vechi = mem::replace(&mut scor, 0);
println!("scor vechi: {vechi}, scor nou: {scor}");
}
Rezultat
fost: Ion, acum: Maria
scor vechi: 87, scor nou: 0
Greșeli frecvente
- Clonezi un câmp mare doar ca să-l poți muta (
let v = self.date.clone();):mem::replacesaumem::takeevită copierea.
Comenzi înrudite
mem::take: Mută valoarea afară dintr-un loc mutabil și lasă în loc valoarea implicită a tipului (text gol, vector gol, 0).mem::swap: Schimbă între ele valorile din două locuri mutabile, fără copiere și fără variabilă temporară.Option::take: take scoate valoarea și lasă None în loc; replace pune o valoare nouă și o returnează pe cea veche.