00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Vettori in Rust

Vec<T> è il tipo di collezione dinamica più utilizzato in Rust. A differenza degli array, i vettori possono crescere e ridursi a runtime e sono allocati sullo heap.

Creare un Vettore

fn main() {
    // Con Vec::new()
    let mut numeri: Vec<i32> = Vec::new();

    // Con la macro vec!
    let numeri = vec![1, 2, 3, 4, 5];

    // Con valore ripetuto
    let zeri = vec![0; 10]; // 10 zeri

    // Con capacità pre-allocata
    let mut buffer = Vec::with_capacity(100);
}

Aggiungere Elementi

fn main() {
    let mut v = Vec::new();

    v.push(1);
    v.push(2);
    v.push(3);

    // Aggiungere più elementi
    v.extend([4, 5, 6]);

    // Inserire a una posizione specifica
    v.insert(0, 0); // [0, 1, 2, 3, 4, 5, 6]

    println!("{:?}", v);
}

Accesso agli Elementi

fn main() {
    let v = vec![10, 20, 30, 40, 50];

    // Con indice (panic se fuori range)
    println!("{}", v[0]); // 10

    // Con get (restituisce Option)
    match v.get(10) {
        Some(val) => println!("{}", val),
        None => println!("Indice fuori range"),
    }

    // Primo e ultimo
    println!("{:?}", v.first()); // Some(10)
    println!("{:?}", v.last());  // Some(50)
}

Rimuovere Elementi

fn main() {
    let mut v = vec![1, 2, 3, 4, 5];

    let ultimo = v.pop();            // Some(5), v = [1, 2, 3, 4]
    let secondo = v.remove(1);       // 2, v = [1, 3, 4]
    v.swap_remove(0);                // Rimuove indice 0, veloce ma non mantiene l'ordine

    // Rimuovere con condizione
    v.retain(|&x| x > 2);

    v.clear(); // Svuota il vettore
}

Iterare

let v = vec![1, 2, 3];

// Riferimento immutabile
for val in &v {
    println!("{}", val);
}

// Riferimento mutabile
let mut v = vec![1, 2, 3];
for val in &mut v {
    *val *= 2;
}
println!("{:?}", v); // [2, 4, 6]

// Consumo (prende ownership)
for val in v {
    println!("{}", val);
}
// v non è più utilizzabile qui

Ordinamento

fn main() {
    let mut numeri = vec![3, 1, 4, 1, 5, 9];

    numeri.sort();                    // [1, 1, 3, 4, 5, 9]
    numeri.sort_by(|a, b| b.cmp(a)); // [9, 5, 4, 3, 1, 1] (decrescente)

    // Ordinamento per float
    let mut decimali = vec![3.1, 1.5, 2.7];
    decimali.sort_by(|a, b| a.partial_cmp(b).unwrap());
}

Metodi Utili

fn main() {
    let v = vec![1, 2, 3, 2, 4, 2, 5];

    println!("{}", v.len());          // 7
    println!("{}", v.is_empty());     // false
    println!("{}", v.contains(&3));   // true

    // Deduplicare (richiede ordinamento)
    let mut v2 = vec![1, 1, 2, 2, 3];
    v2.dedup();
    println!("{:?}", v2); // [1, 2, 3]

    // Slice da un vettore
    let porzione = &v[1..4]; // [2, 3, 2]

    // Concatenare vettori
    let a = vec![1, 2];
    let b = vec![3, 4];
    let c = [a, b].concat(); // [1, 2, 3, 4]
}

Capacità e Performance

fn main() {
    let mut v = Vec::with_capacity(10);
    println!("Len: {}, Cap: {}", v.len(), v.capacity()); // 0, 10

    for i in 0..10 {
        v.push(i); // Nessuna riallocazione
    }

    v.push(10); // Qui avviene una riallocazione

    v.shrink_to_fit(); // Riduce la capacità alla lunghezza
}

Trasformazioni con Iteratori

let numeri = vec![1, 2, 3, 4, 5];

let doppi: Vec<i32> = numeri.iter().map(|x| x * 2).collect();
let pari: Vec<&i32> = numeri.iter().filter(|x| *x % 2 == 0).collect();
let somma: i32 = numeri.iter().sum();

println!("{:?}", doppi); // [2, 4, 6, 8, 10]
println!("{:?}", pari);  // [2, 4]
println!("{}", somma);   // 15

Conclusione

Vec<T> è la collezione più versatile in Rust, ideale per liste di dimensione variabile. Pre-allocare la capacità con Vec::with_capacity migliora le performance quando la dimensione approssimativa è nota. Combinato con gli iteratori, Vec offre un modo potente e idiomatico per manipolare collezioni di dati.