Salta ai contenuti

Array in Rust

Un array è una lista di valori a dimensione fissa, tutti dello stesso tipo. «Dimensione fissa» è la parola chiave: una volta creato, un array non può crescere né rimpicciolirsi. Se ti serve qualcosa che cambia dimensione, per quello c’è il vettore.

fn main() {
let numbers: [i32; 5] = [1, 2, 3, 4, 5];
println!("{:?}", numbers);
}

Il tipo [i32; 5] si legge «un array di 5 valori i32». La lunghezza fa parte del tipo: [i32; 5] e [i32; 3] sono considerati tipi diversi.

▶ Provalo tu

Puoi anche lasciare che Rust deduca il tipo e scrivere solo i valori:

let numbers = [1, 2, 3, 4, 5];

Per riempire un array con lo stesso valore N volte, usa questa scorciatoia:

fn main() {
let zeros = [0; 5]; // [0, 0, 0, 0, 0]
println!("{:?}", zeros);
}
▶ Provalo tu

Gli indici di un array partono da 0 e si scrivono tra parentesi quadre:

fn main() {
let fruits = ["mela", "banana", "ciliegia"];
println!("{}", fruits[0]); // mela
println!("{}", fruits[2]); // ciliegia
println!("Lunghezza: {}", fruits.len());
}
▶ Provalo tu

Prova a leggere un indice che non esiste: Rust ferma il programma invece di leggere in silenzio memoria spazzatura:

fn get_fruit(fruits: [&str; 3], index: usize) -> &str {
fruits[index]
}
fn main() {
let fruits = ["mela", "banana", "ciliegia"];
println!("{}", get_fruit(fruits, 10)); // va in panic durante l'esecuzione
}
thread 'main' (12345) panicked at src/main.rs:2:5:
index out of bounds: the len is 3 but the index is 10

Il messaggio di panic resta in inglese, come lo stampa Rust: dice che l’indice è fuori dai limiti, perché la lunghezza è 3 ma l’indice è 10.

fn main() {
let numbers = [10, 20, 30];
for n in numbers {
println!("{n}");
}
}
▶ Provalo tu

Un array può contenere altri array. Così ottieni una griglia con righe e colonne, come una scacchiera o un piccolo foglio di calcolo. Il tipo di grid qui sotto è [[i32; 3]; 2], che si legge «2 righe, ognuna un array di 3 valori i32».

fn main() {
// 2 righe, 3 colonne
let grid = [
[1, 2, 3],
[4, 5, 6],
];
println!("Riga 1, colonna 2: {}", grid[1][2]);
let mut total = 0;
for row in grid {
println!("{:?}", row);
for value in row {
total += value;
}
}
println!("Totale: {total}");
}

Output:

Riga 1, colonna 2: 6
[1, 2, 3]
[4, 5, 6]
Totale: 21
▶ Provalo tu

grid[1][2] significa «riga 1, poi colonna 2 dentro quella riga». Entrambi gli indici partono da 0, quindi è la seconda riga, terzo valore. Per visitare ogni valore usa un ciclo per le righe e, dentro, un secondo ciclo per i valori di ogni riga.

Tutte le righe devono avere la stessa lunghezza, perché la lunghezza della riga fa parte del tipo. Se mentre scorri ti serve anche la posizione, .iter().enumerate() ti dà indice e valore insieme. Lo trovi nella pagina sul ciclo for.

Usa un array quando la dimensione è fissa e la conosci in anticipo (come i sette giorni della settimana). Usa un Vec quando devi aggiungere o togliere elementi, cioè, in pratica, quasi sempre. Nel codice Rust di tutti i giorni gli array sono meno comuni dei vettori.

Crea l’array [4, 8, 15, 16, 23, 42]. Somma tutti i valori, poi stampa la somma e la media con due cifre decimali. Suggerimento: scorri con for, tieni un total parziale e converti entrambi i numeri in f64 con as prima di dividere.

Mostra la soluzione
fn main() {
let numbers = [4, 8, 15, 16, 23, 42];
let mut total = 0;
for n in numbers {
total += n;
}
let average = total as f64 / numbers.len() as f64;
println!("Somma: {total}");
println!("Media: {average:.2}");
}

Output:

Somma: 108
Media: 18.00
▶ Provalo tu

Senza as f64, total / numbers.len() sarebbe una divisione intera, e Rust si lamenterebbe anche che total (un i32) e len() (un usize) sono di tipi diversi.

Hai le temperature di una settimana: [18, 25, 12, 31, 22, 27, 19]. Trova e stampa la più alta. Suggerimento: parti da let mut hottest = temps[0];, poi scorri e sostituiscila ogni volta che trovi un valore più grande.

Mostra la soluzione
fn main() {
let temps = [18, 25, 12, 31, 22, 27, 19];
let mut hottest = temps[0];
for t in temps {
if t > hottest {
hottest = t;
}
}
println!("Giorno più caldo: {hottest}");
}

Output:

Giorno più caldo: 31
▶ Provalo tu

Partire da temps[0] invece che da 0 è importante: se tutte le temperature fossero sotto zero, partire da 0 darebbe una risposta sbagliata.

  • Gli array hanno una lunghezza fissa che fa parte del loro tipo: [i32; 5].
  • Leggi gli elementi con array[indice], a partire da 0.
  • Un accesso fuori dai limiti va in panic durante l’esecuzione invece di causare un comportamento indefinito.
  • Gli array possono contenere array: [[i32; 3]; 2] è una griglia che leggi con grid[riga][colonna].
  • Se devi cambiare dimensione, usa invece un Vec.

Verifica veloce

1. Che cosa è vero sulla lunghezza di un array in Rust?

2. Che cosa succede se durante l'esecuzione accedi a un indice fuori dai limiti di un array?

3. Che cosa crea let zeros = [0; 5]; ?

Punteggio: 0 / 3