Vec::push în Rust

push adaugă un element la sfârșitul vectorului; pop îl scoate pe ultimul și îl returnează ca Option.

Sintaxă
pub fn push(&mut self, value: T)
pub fn pop(&mut self) -> Option<T>

Ce face Vec::push

push mută valoarea primită la finalul vectorului. Dacă nu mai este loc, vectorul își mărește singur memoria. Vectorul trebuie să fie mut, pentru că se modifică.

pop face invers: scoate ultimul element și îl returnează. Pentru că vectorul poate fi gol, rezultatul este un Option<T>: Some(element) sau None. Nu există panic la un vector gol.

Împreună, push și pop fac din Vec o stivă (ultimul intrat, primul ieșit): istoricul pentru „Anulează”, verificarea parantezelor, parcurgerea în adâncime. Ambele operații sunt foarte rapide. Pentru o coadă (primul intrat, primul ieșit) folosește VecDeque.

Parametri

Parametru Descriere
value Elementul de adăugat. Este mutat în vector (pentru String și alte tipuri care nu sunt Copy, variabila originală nu mai poate fi folosită).

Ce returnează

push nu returnează nimic. pop returnează Some(ultimul) sau None dacă vectorul este gol.

Exemple

Exemplul 1: Coșul de cumpărături

fn main() {
    let mut cos = Vec::new();
    cos.push("mere");
    cos.push("brânză");
    cos.push("cafea");
    println!("{:?}", cos);

    let ultimul = cos.pop();
    println!("pop() = {:?}, rămân {:?}", ultimul, cos);

    let mut gol: Vec<&str> = Vec::new();
    println!("pop() pe vector gol = {:?}", gol.pop());
}

Rezultat

["mere", "brânză", "cafea"]
pop() = Some("cafea"), rămân ["mere", "brânză"]
pop() pe vector gol = None

Exemplul 2: Istoric pentru „Anulează” (stivă)

while let Some(..) = v.pop() scoate elementele de la ultimul la primul și se oprește singur când vectorul se golește.

fn main() {
    let mut istoric = Vec::new();
    for actiune in ["scrie titlul", "adaugă imaginea", "schimbă fontul"] {
        istoric.push(actiune);
        println!("făcut: {actiune}");
    }
    while let Some(actiune) = istoric.pop() {
        println!("anulez: {actiune}");
    }
    println!("istoric gol: {}", istoric.is_empty());
}

Rezultat

făcut: scrie titlul
făcut: adaugă imaginea
făcut: schimbă fontul
anulez: schimbă fontul
anulez: adaugă imaginea
anulez: scrie titlul
istoric gol: true

Exemplul 3: Parantezele se închid corect?

Fiecare paranteză deschisă intră în stivă. La o paranteză închisă, ultima deschisă trebuie să fie perechea ei. Comparăm direct Option-ul primit de la pop cu Some(pereche).

fn echilibrat(text: &str) -> bool {
    let mut stiva = Vec::new();
    for c in text.chars() {
        match c {
            '(' | '[' | '{' => stiva.push(c),
            ')' | ']' | '}' => {
                let pereche = match c {
                    ')' => '(',
                    ']' => '[',
                    _ => '{',
                };
                if stiva.pop() != Some(pereche) {
                    return false;
                }
            }
            _ => {}
        }
    }
    stiva.is_empty()
}

fn main() {
    for t in ["(a + b) * [c - d]", "{[()]}", "(a + b", "(]"] {
        println!("{t:20} -> {}", echilibrat(t));
    }
}

Rezultat

(a + b) * [c - d]    -> true
{[()]}               -> true
(a + b               -> false
(]                   -> false

Greșeli frecvente

  • Scrii let x: i32 = v.pop();. pop returnează Option<i32>, deci compilatorul dă mismatched types. Tratează ambele cazuri cu if let Some(x) = v.pop(), match sau unwrap_or.
  • Uiți mut: let v = Vec::new(); v.push(1); dă cannot borrow `v` as mutable, as it is not declared as mutable.
  • Adaugi în vector în timp ce îl parcurgi cu for x in &v. Compilatorul refuză (împrumut mutabil și imutabil în același timp). Adaugă într-un vector separat sau parcurge după indici, cu lungimea salvată înainte.

Comenzi înrudite

  • Vec: Vectorul dinamic din Rust: o listă de elemente de același tip, ținute unul după altul în memorie, care crește singură.
  • Vec::insert: insert pune un element pe o poziție anume și împinge restul la dreapta; remove scoate elementul de pe o poziție.
  • Vec::extend_from_slice: extend_from_slice adaugă copii ale elementelor dintr-un slice; append mută toate elementele altui vector și îl golește.
  • VecDeque::push_back: Adaugă (push) și scoate (pop) elemente la oricare capăt al cozii: back este sfârșitul, front este începutul.
  • Vec::len: len returnează numărul de elemente din vector; is_empty spune dacă vectorul nu are niciun element.