Lezioni del modulo (1/2)
Variabili e mutabilità
In Rust, la gestione delle variabili e della memoria è guidata da due principi fondamentali: la sicurezza e il controllo. Per questo motivo, a differenza di molti altri linguaggi di programmazione, in Rust le variabili sono immutabili di default.
Questo significa che una volta assegnato un valore a una variabile, questo non può essere modificato. Se si tenta di farlo, il compilatore genererà un errore.
Variabili Immutabili e Parola Chiave mut
Per dichiarare una variabile si usa la parola chiave let:
let x = 5; // Immutabile di default
// x = 6; // ERRORE! Il compilatore si rifiuterà di compilare.
Se hai la necessità di modificare il valore di una variabile, devi renderla esplicitamente mutabile usando la parola chiave mut subito dopo let:
let mut y = 10; // Mutabile
println!("Il valore di y e: {}", y);
y = 15; // Valido!
println!("Il valore modificato di y e: {}", y);
L'uso del prefisso mut comunica chiaramente al compilatore e a chi legge il codice che quel valore cambierà nel corso dell'esecuzione.
Shadowing (Ombreggiatura)
Rust permette anche il concetto di shadowing, ovvero la ri-dichiarazione di una variabile con lo stesso nome usando nuovamente la parola chiave let. La nuova variabile "copre" (o mette in ombra) la precedente:
let x = 5;
let x = x + 1; // Shadowing: x ora vale 6
let x = x * 2; // Shadowing: x ora vale 12
A differenza di mut, lo shadowing ti permette di:
- Cambiare il tipo di dato di una variabile mantenendo lo stesso nome.
- Mantenere l'immutabilità della variabile dopo le trasformazioni.
let spaces = " "; // Tipo: &str (stringa)
let spaces = spaces.len(); // Tipo: usize (numero intero)
Utilità dello Shadowing e gli Scope
Lo shadowing non è limitato allo stesso blocco; può essere utilizzato all'interno di blocchi annidati ({}) per sovrascrivere temporaneamente un valore. Quando il blocco interno termina, la variabile originale torna a essere visibile:
let x = 5;
{
let x = x * 2; // Shadowing valido solo all'interno del blocco
println!("Valore nel blocco interno: {}", x); // Stampa 10
}
println!("Valore nel blocco esterno: {}", x); // Stampa 5
Questo meccanismo è estremamente sicuro ed efficiente perché avviene interamente a tempo di compilazione, garantendo la sicurezza dei tipi senza alcun costo di performance a runtime.
Prova tu
Dichiara una variabile mutabile chiamata x con valore iniziale 5. Successivamente aggiungi 10 a x e stampala a schermo usando la macro println!.
Mostra suggerimento
Dichiara la variabile con `let mut x = 5;`, poi incrementala con `x += 10;` (o `x = x + 10;`) ed infine stampala con `println!('{}', x);`.
Soluzione disponibile dopo 3 tentativi
Dichiara una variabile immutabile y con valore 10. Esegui lo shadowing di y dichiarandola di nuovo con let per moltiplicare il suo valore precedente per 2, e infine stampala usando println!.
Mostra suggerimento
Usa `let y = 10;`, poi fai shadowing dichiarandola di nuovo con `let y = y * 2;` e infine usa `println!` per visualizzarla.
Soluzione disponibile dopo 3 tentativi
Dichiara una variabile immutabile input contenente il valore stringa "42". Esegui lo shadowing di input dichiarandola come un intero di tipo i32 convertendo il valore originale tramite input.parse::<i32>().unwrap(). Infine stampala usando la macro println!.
Mostra suggerimento
Dichiara `let input = "42";`, poi fai shadowing con `let input: i32 = input.parse().unwrap();` e stampala con `println!("{}", input);`.
Soluzione disponibile dopo 3 tentativi