Array in Rust
Gli array in Rust sono collezioni di elementi dello stesso tipo con una dimensione fissa nota a compile-time. Vengono allocati sullo stack, rendendoli molto efficienti.
Dichiarazione e Inizializzazione
Il tipo di un array è [T; N] dove T è il tipo degli elementi e N la dimensione:
fn main() {
// Tipo esplicito
let numeri: [i32; 5] = [1, 2, 3, 4, 5];
// Tipo inferito
let nomi = ["Alice", "Bob", "Carlo"];
// Inizializzazione con valore ripetuto
let zeri = [0; 10]; // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
}
Accesso agli Elementi
fn main() {
let numeri = [10, 20, 30, 40, 50];
println!("{}", numeri[0]); // 10
println!("{}", numeri[4]); // 50
// Accesso sicuro con get()
match numeri.get(10) {
Some(valore) => println!("{}", valore),
None => println!("Indice fuori range"),
}
// numeri[10] causerebbe un PANIC a runtime
}
Lunghezza di un Array
let arr = [1, 2, 3, 4, 5];
println!("Lunghezza: {}", arr.len()); // 5
println!("È vuoto: {}", arr.is_empty()); // false
Iterare sugli Elementi
let frutti = ["mela", "pera", "banana"];
// Con for-in
for frutto in &frutti {
println!("{}", frutto);
}
// Con indice
for i in 0..frutti.len() {
println!("{}: {}", i, frutti[i]);
}
// Con enumerate
for (i, frutto) in frutti.iter().enumerate() {
println!("{}: {}", i, frutto);
}
Array Mutabili
fn main() {
let mut numeri = [1, 2, 3, 4, 5];
numeri[0] = 10;
numeri[4] = 50;
println!("{:?}", numeri); // [10, 2, 3, 4, 50]
}
Metodi Utili
fn main() {
let mut numeri = [3, 1, 4, 1, 5, 9];
// Ordinamento
numeri.sort();
println!("{:?}", numeri); // [1, 1, 3, 4, 5, 9]
// Ricerca
println!("{}", numeri.contains(&4)); // true
// Primo e ultimo
println!("{:?}", numeri.first()); // Some(1)
println!("{:?}", numeri.last()); // Some(9)
// Invertire
numeri.reverse();
println!("{:?}", numeri); // [9, 5, 4, 3, 1, 1]
// Finestre e chunk
let finestre: Vec<&[i32]> = numeri.windows(3).collect();
let gruppi: Vec<&[i32]> = numeri.chunks(2).collect();
}
Confronto tra Array
fn main() {
let a = [1, 2, 3];
let b = [1, 2, 3];
let c = [4, 5, 6];
println!("{}", a == b); // true
println!("{}", a == c); // false
}
Array come Parametro di Funzione
// Dimensione fissa
fn somma_tre(arr: [i32; 3]) -> i32 {
arr[0] + arr[1] + arr[2]
}
// Slice (riferimento a qualsiasi dimensione)
fn somma(arr: &[i32]) -> i32 {
arr.iter().sum()
}
fn main() {
let numeri = [1, 2, 3, 4, 5];
println!("{}", somma(&numeri)); // 15
}
Array Multi-dimensionali
fn main() {
let matrice: [[i32; 3]; 2] = [
[1, 2, 3],
[4, 5, 6],
];
println!("{}", matrice[1][2]); // 6
for riga in &matrice {
for valore in riga {
print!("{} ", valore);
}
println!();
}
}
Conclusione
Gli array in Rust sono ideali quando la dimensione è nota a compile-time e si vuole massimizzare la performance con l’allocazione sullo stack. Per collezioni di dimensione variabile, usa Vec<T>. Ricorda che la dimensione fa parte del tipo: [i32; 3] e [i32; 5] sono tipi diversi.