Rust offre un insieme ricco e versatile di collezioni per gestire e manipolare dati in modo sicuro ed efficiente. In questa lezione, esploreremo le collezioni più comuni, come array, slice, vettori, HashMap e BTreeMap. Inoltre, imparerai a lavorare con gli iteratori e metodi funzionali per elaborare dati in modo dichiarativo.
Un array in Rust è una collezione di elementi con dimensione fissa. Ogni elemento deve avere lo stesso tipo.
fn main() {
let numeri = [1, 2, 3, 4, 5]; // Array di 5 elementi
println!("Primo elemento: {}", numeri[0]);
println!("Lunghezza: {}", numeri.len());
}
Gli array sono ideali per dati con dimensioni conosciute a tempo di compilazione.
Una slice è una vista su una porzione di un array o un vettore. Ti consente di lavorare su una parte dei dati senza copiarli.
fn main() {
let numeri = [1, 2, 3, 4, 5];
let slice = &numeri[1..4]; // Slice degli elementi da indice 1 a 3
println!("{:?}", slice);
}
I vettori sono una collezione dinamica che può crescere o ridursi a runtime. Sono molto comuni in Rust.
fn main() {
let mut numeri = vec![1, 2, 3];
numeri.push(4); // Aggiungi un elemento
println!("{:?}", numeri);
numeri.pop(); // Rimuovi l'ultimo elemento
println!("{:?}", numeri);
}
I vettori offrono metodi utili come push
, pop
, e len
per manipolare i dati.
Un HashMap
è una collezione chiave-valore non ordinata. È utile per cercare dati in modo rapido.
use std::collections::HashMap;
fn main() {
let mut studenti = HashMap::new();
studenti.insert("Alice", 85);
studenti.insert("Bob", 92);
if let Some(&punteggio) = studenti.get("Alice") {
println!("Punteggio di Alice: {}", punteggio);
}
for (nome, punteggio) in &studenti {
println!("{}: {}", nome, punteggio);
}
}
Un BTreeMap
è simile a HashMap
, ma mantiene le chiavi ordinate.
use std::collections::BTreeMap;
fn main() {
let mut numeri = BTreeMap::new();
numeri.insert(3, "Tre");
numeri.insert(1, "Uno");
numeri.insert(2, "Due");
for (chiave, valore) in &numeri {
println!("{}: {}", chiave, valore);
}
}
Gli iteratori permettono di scorrere e trasformare i dati in modo dichiarativo. Puoi creare un iteratore da collezioni come vettori, array o slice.
for
fn main() {
let numeri = vec![1, 2, 3, 4, 5];
for n in &numeri {
println!("{}", n);
}
}
map
e filter
map
: Trasforma ogni elemento.filter
: Seleziona elementi che soddisfano una condizione.fn main() {
let numeri = vec![1, 2, 3, 4, 5];
// Moltiplica ogni elemento per 2
let doppi = numeri.iter().map(|x| x * 2).collect::>();
println!("{:?}", doppi);
// Filtra numeri pari
let pari = numeri.iter().filter(|&&x| x % 2 == 0).collect::>();
println!("{:?}", pari);
}
Elaborare Dati da un Array
Scrivi una funzione che accetta un array di numeri interi e restituisce un vettore con i numeri moltiplicati per 3.
Soluzione:
fn moltiplica(array: &[i32]) -> Vec {
array.iter().map(|x| x * 3).collect()
}
fn main() {
let numeri = [1, 2, 3, 4, 5];
let risultato = moltiplica(&numeri);
println!("{:?}", risultato);
}
Trovare Valori Duplicati
Scrivi una funzione che trova e restituisce i numeri duplicati in un vettore.
Soluzione:
use std::collections::HashSet;
fn trova_duplicati(vettore: &[i32]) -> Vec {
let mut visti = HashSet::new();
let mut duplicati = Vec::new();
for &numero in vettore {
if !visti.insert(numero) {
duplicati.push(numero);
}
}
duplicati
}
fn main() {
let numeri = vec![1, 2, 3, 4, 1, 2, 5];
let duplicati = trova_duplicati(&numeri);
println!("Duplicati: {:?}", duplicati);
}
Le collezioni e gli iteratori in Rust ti forniscono strumenti potenti per gestire e manipolare dati in modo flessibile ed efficiente. Comprendere il funzionamento di array, slice, vettori, HashMap
, BTreeMap
ti permetterà di scrivere codice più chiaro e conciso. Nel prossimo articolo esploreremo metodi funzionali come Closure, Map e Filter. Prova gli esercizi proposti per consolidare i concetti e padroneggiare l'uso di collezioni e iteratori in Rust!