mem::swap în Rust

Schimbă între ele valorile din două locuri mutabile, fără copiere și fără variabilă temporară.

Sintaxă
use std::mem;

pub fn swap<T>(x: &mut T, y: &mut T)

Ce face mem::swap

mem::swap(&mut a, &mut b) interschimbă valorile: după apel, a are ce avea b și invers. Funcționează pentru orice tip, chiar și pentru cele care nu pot fi copiate sau clonate, pentru că mută doar octeții.

Pentru două elemente din același vector nu poți avea două &mut deodată; acolo folosește v.swap(i, j).

Parametri

Parametru Descriere
x Primul loc, prin &mut.
y Al doilea loc, prin &mut.

Ce returnează

Nimic.

Exemple

Exemplul 1: Interschimbare de texte

use std::mem;

fn main() {
    let mut tura_zi = String::from("Ana");
    let mut tura_noapte = String::from("Mihai");

    mem::swap(&mut tura_zi, &mut tura_noapte);
    println!("ziua: {tura_zi}, noaptea: {tura_noapte}");
}

Rezultat

ziua: Mihai, noaptea: Ana

Exemplul 2: Buffer dublu: listele își schimbă rolurile

La fiecare pas calculăm generația nouă în urmator, apoi o schimbăm cu curent. Nu se alocă vectori noi.

use std::mem;

fn main() {
    let mut curent = vec![1, 2, 3];
    let mut urmator = Vec::new();

    for pas in 1..=3 {
        urmator.clear();
        urmator.extend(curent.iter().map(|x| x * 2));
        mem::swap(&mut curent, &mut urmator);
        println!("pasul {pas}: {curent:?}");
    }

    let mut v = vec!["a", "b", "c"];
    v.swap(0, 2);
    println!("{v:?}");
}

Rezultat

pasul 1: [2, 4, 6]
pasul 2: [4, 8, 12]
pasul 3: [8, 16, 24]
["c", "b", "a"]

Greșeli frecvente

  • Scrii mem::swap(&mut v[0], &mut v[1]): nu compilează (două împrumuturi mutabile ale lui v). Folosește v.swap(0, 1).
  • Pentru numere simple, (a, b) = (b, a); este la fel de clar.

Comenzi înrudite

  • mem::replace: Pune o valoare nouă într-un loc mutabil și returnează valoarea veche, mutată afară.
  • mem::take: Mută valoarea afară dintr-un loc mutabil și lasă în loc valoarea implicită a tipului (text gol, vector gol, 0).
  • Option::take: take scoate valoarea și lasă None în loc; replace pune o valoare nouă și o returnează pe cea veche.