Variabili in Rust
Una variabile è semplicemente un nome che dai a un valore per poterlo usare più tardi. Pensala come una scatola con un’etichetta: ci metti dentro qualcosa, ci scrivi sopra un nome, e la chiami con quel nome invece di ripetere il valore dappertutto.
Creare una variabile
Sezione intitolata “Creare una variabile”In Rust crei una variabile con la parola chiave let:
fn main() { let age = 30; println!("Ho {age} anni");}Output:
Ho 30 anniSmontiamo quella riga:
let: dice a Rust «sto creando una nuova variabile».age: il nome che abbiamo scelto.=: assegna il valore a destra al nome a sinistra.30: il valore che stiamo salvando.
L’{age} dentro println! stampa il valore della variabile. Si chiama interpolazione di stringhe: Rust sostituisce {age} con quello che contiene age.
Il tipo lo capisce Rust
Sezione intitolata “Il tipo lo capisce Rust”Ogni valore in Rust ha un tipo (un numero intero, del testo, true/false e così via). Potresti aspettarti di doverlo dichiarare, ma di solito non serve: Rust guarda il valore e lo deduce da solo. Si chiama inferenza di tipo.
fn main() { let score = 95; // Rust deduce che è un intero let name = "Ferris"; // Rust deduce che è testo let is_active = true; // Rust deduce che è un booleano println!("{name}: {score}, attivo = {is_active}");}Output:
Ferris: 95, attivo = trueSe vuoi essere esplicito, puoi scrivere il tipo dopo i due punti:
let score: i32 = 95; // i32 = un intero a 32 bitLe variabili sono immutabili per default
Sezione intitolata “Le variabili sono immutabili per default”Ecco la parte che sorprende chi arriva da altri linguaggi: in Rust, una volta assegnata una variabile, per default non puoi cambiarla. «Immutabile» significa proprio che non si può cambiare.
Questo codice non compila:
fn main() { let count = 1; count = 2; // ❌ errore: non puoi assegnare due volte una variabile immutabile println!("{count}");}Il compilatore ti ferma con un messaggio chiaro:
error[E0384]: cannot assign twice to immutable variable `count`Cioè: non puoi assegnare due volte la variabile immutabile count.
Perché un linguaggio dovrebbe farlo apposta? Perché tanti bug nascono da valori che cambiano quando non te lo aspetti. Rendendo le cose immutabili a meno che tu non chieda di poterle cambiare, Rust rende il tuo codice più prevedibile. È una caratteristica, non un limite.
Rendere modificabile una variabile con mut
Sezione intitolata “Rendere modificabile una variabile con mut”Quando hai davvero bisogno che un valore cambi, aggiungi la parola chiave mut (abbreviazione di mutable, cioè modificabile):
fn main() { let mut count = 1; println!("Prima: {count}");
count = 2; // ✅ ora è permesso, grazie a `mut` println!("Dopo: {count}");}Output:
Prima: 1Dopo: 2Shadowing: riusare lo stesso nome
Sezione intitolata “Shadowing: riusare lo stesso nome”Rust ti permette di dichiarare una variabile nuova con lo stesso nome di una vecchia. Si chiama shadowing (oscuramento): la nuova «fa ombra» alla vecchia:
fn main() { let x = 5; let x = x + 1; // una nuova x, basata sulla vecchia x -> 6 let x = x * 2; // un'altra nuova x -> 12 println!("x vale {x}");}Output:
x vale 12Sembra simile a mut, ma è diverso:
mutcambia il valore della stessa variabile.- Lo shadowing crea una variabile completamente nuova che riusa il nome, e può perfino avere un tipo diverso.
Lo shadowing è comodo quando vuoi trasformare un valore ma continuare a usare lo stesso nome:
fn main() { let spaces = " "; // testo let spaces = spaces.len(); // ora è un numero (quanti spazi) println!("Numero di spazi: {spaces}");}Output:
Numero di spazi: 3Costanti
Sezione intitolata “Costanti”Una costante è un valore che non cambia mai ed è fissato in fase di compilazione. La dichiari con const invece di let, e devi scrivere il tipo:
const MAX_SCORE: u32 = 100;
fn main() { println!("Il punteggio massimo è {MAX_SCORE}");}Output:
Il punteggio massimo è 100Per convenzione, le costanti si scrivono in UPPER_SNAKE_CASE. Ecco come si confrontano con le variabili normali:
Variabile let |
Costante const |
|
|---|---|---|
| Può cambiare? | Solo con mut |
Mai |
| Tipo obbligatorio? | Facoltativo (dedotto) | Obbligatorio |
| Stile del nome | snake_case |
UPPER_SNAKE_CASE |
| Dove si può usare | Dentro le funzioni | Ovunque, anche fuori dalle funzioni |
Usa una costante per valori davvero fissi, come il numero di secondi in un minuto o un limite massimo.
Regole per i nomi
Sezione intitolata “Regole per i nomi”- Usa lo
snake_case: parole minuscole unite da trattini bassi, comeuser_name,total_price. - I nomi possono contenere lettere, numeri e trattini bassi, ma non possono cominciare con un numero.
- Scegli nomi descrittivi:
ageè meglio dia.
Pratica
Sezione intitolata “Pratica”1. Sali di livello
Sezione intitolata “1. Sali di livello”Crea una variabile level che parte da 1. Stampala, aumentala di 1 due volte e stampala dopo ogni modifica, così ottieni Livello 1, Livello 2, Livello 3. Suggerimento: un valore che cambia ha bisogno di mut, e level = level + 1; aggiunge uno.
Mostra la soluzione
fn main() { let mut level = 1; println!("Livello {level}");
level = level + 1; println!("Livello {level}");
level = level + 1; println!("Livello {level}");}Output:
Livello 1Livello 2Livello 32. Da minuti a secondi
Sezione intitolata “2. Da minuti a secondi”Dichiara una costante SECONDS_PER_MINUTE uguale a 60. Parti da let time = 5; (in minuti), poi fai lo shadowing di time in modo che contenga la stessa durata in secondi, e stampa Sono 300 secondi. Suggerimento: la nuova time si può costruire dalla vecchia: let time = time * ...;.
Mostra la soluzione
const SECONDS_PER_MINUTE: u32 = 60;
fn main() { let time = 5; // minuti let time = time * SECONDS_PER_MINUTE; // una nuova `time`, ora in secondi println!("Sono {time} secondi");}Output:
Sono 300 secondiNon serve mut: il secondo let crea una variabile completamente nuova che riusa il nome. Qui Rust deduce anche che time è un u32, perché viene moltiplicata per la costante u32.
Riepilogo
Sezione intitolata “Riepilogo”- Crea le variabili con
let; di solito Rust deduce il tipo al posto tuo. - Le variabili sono immutabili per default: aggiungi
mutper permettere le modifiche. - Lo shadowing dichiara di nuovo un nome con
let, creando una nuova variabile (che può cambiare tipo). - Le costanti (
const) non cambiano mai, hanno sempre bisogno di un tipo e usano loUPPER_SNAKE_CASE.
Verifica veloce
Sezione intitolata “Verifica veloce”Verifica veloce
1. Per default, puoi riassegnare una variabile let in Rust?
2. Cos'è lo shadowing in Rust?
3. Secondo questa pagina, quale convenzione di nomi usano le variabili in Rust?
Punteggio: 0 / 3
Per approfondire
Sezione intitolata “Per approfondire”- Variables and Mutability — The Rust Book (in inglese): il capitolo ufficiale su
let,mut, costanti e sul perché l’immutabilità è il default. - Shadowing — The Rust Book (in inglese): di più su come lo shadowing differisce da
mut, compreso il cambio di tipo di un valore. - Variable Bindings — Rust by Example (in inglese): brevi esempi eseguibili, con approfondimenti su mutabilità e scope e shadowing.
- Constants — Rust by Example (in inglese):
const(e il suo cuginostatic) in un piccolo programma. - La parola chiave
let— documentazione della libreria standard (in inglese): tutto quello cheletsa fare, per quando vuoi il quadro completo.