Capitolo 2: Comprendere le variabili e i tipi in Dart e Flutter
Al termine di questo capitolo sarai in grado di distinguere tra linguaggi statici e dinamici, utilizzare correttamente var
, final
, const
e dynamic
, e applicare queste conoscenze attraverso esercizi pratici.
Introduzione al Capitolo 2
La gestione dei dati è fondamentale in ogni linguaggio di programmazione. In Dart e Flutter, questo avviene tramite variabili e il sistema di tipi.
Sebbene Dart sia un linguaggio tipizzato staticamente, offre anche funzionalità di tipizzazione dinamica quando necessario, fornendo flessibilità agli sviluppatori.
Linguaggi Statici vs Dinamici
I linguaggi di programmazione si classificano generalmente in due categorie in base alla gestione dei tipi di dati: statici e dinamici.
Tipizzazione Statica
- Definizione: Nei linguaggi a tipizzazione statica, il tipo di una variabile è determinato durante la compilazione e non può cambiare.
- Esempi di linguaggi: Java, C++, Dart (per impostazione predefinita).
- Vantaggi:
- Rilevazione precoce degli errori: Gli errori di tipo vengono individuati durante la compilazione, riducendo i problemi a runtime.
- Prestazioni migliorate: La conoscenza dei tipi in fase di compilazione ottimizza l'esecuzione del codice.
- Manutenibilità: Il codice è più leggibile e facile da mantenere grazie alla chiarezza dei tipi.
Esempio in Dart:
int eta = 30; // Dichiarazione di una variabile intera.
eta = "trenta"; // Errore di compilazione: non si può assegnare una stringa a un intero.
Tipizzazione Dinamica
- Definizione: Nei linguaggi a tipizzazione dinamica, il tipo di una variabile è determinato durante l'esecuzione, permettendo alla variabile di contenere dati di tipi diversi nel tempo.
- Esempi di linguaggi: JavaScript, Python.
- Vantaggi:
- Flessibilità: Le variabili possono contenere dati di qualsiasi tipo, adattandosi a diverse situazioni.
- Semplicità sintattica: La sintassi è spesso più semplice, facilitando l'apprendimento per i principianti.
numero = 10 # Inizialmente un intero.
numero = "dieci" # Ora una stringa. Consentito in tipizzazione dinamica.
Dart: Un Approccio Ibrido
- Flessibilità: Pur essendo tipizzato staticamente, Dart permette l'uso dinamico dei tipi tramite la parola chiave
dynamic
, offrendo il meglio di entrambi gli approcci.
Inferenza dei tipi con var
In Dart, la parola chiave var
consente l'inferenza del tipo di una variabile basandosi sul valore assegnato.
Una volta determinato, il tipo non può cambiare.
Esempio:
var nome = "Luca"; // Dart inferisce che 'nome' è di tipo String.
nome = 25; // Errore: non si può assegnare un intero a una variabile di tipo String.
Punti Chiave:
- Uso di
var
: Utile quando il tipo della variabile è evidente dal contesto. - Immutabilità del tipo: Dopo l'inferenza, il tipo della variabile è fisso.
La parola chiave final
La parola chiave final
dichiara una variabile il cui valore non può essere riassegnato dopo l'inizializzazione. Tuttavia, se il valore è un oggetto mutabile, come una lista, l'oggetto stesso può essere modificato.
final città = "Roma";
città = "Milano"; // Errore: non si può riassegnare una variabile final.
final List<int> numeri = [1, 2, 3];
numeri.add(4); // Consentito: la lista è mutabile, anche se la variabile è final.
Quando Usare final
:
- Costanti a runtime: Quando il valore è determinato durante l'esecuzione e non deve cambiare.
La parola chiave const
La parola chiave const
definisce costanti a tempo di compilazione.
A differenza di final
, il valore deve essere noto e immutabile durante la compilazione.
Gli oggetti creati con const
sono canonicalizzati, ovvero istanze identiche condividono la stessa posizione in memoria.
const pi = 3.14;
const area = pi * 2 * 2; // Calcolo a tempo di compilazione.
final ora = DateTime.now(); // Consentito con 'final'.
const oraConst = DateTime.now(); // Errore: 'const' richiede un valore noto a tempo di compilazione.
Differenze chiave tra final
e const
:
Final
Mutabilità - Immutabile dopo l'inizializzazione
Utilizzo - Immutabile e noto a tempo di compilazione
Const
Mutabilità - Immutabile e noto a tempo di compilazione
Utilizzo - Valori determinati a runtime - Valori determinati a compile-time
In questa pagina ho scritto un approfondimento in merito.
Esercizio 1: Utilizzo di var
, final
e const
- Dichiara una variabile usando
var
per memorizzare il titolo del tuo libro preferito. - Dichiara una variabile
final
per memorizzare il tuo anno di nascita. Prova a cambiarne il valore e osserva cosa accade. - Usa
const
per dichiarare il valore di Pi greco (3.14159). Utilizzalo per calcolare la circonferenza di un cerchio con raggio 5.
La parola chiave dynamic
In Dart, la parola chiave dynamic
permette di dichiarare variabili il cui tipo può essere determinato durante l'esecuzione.
A differenza di var
, che inferisce il tipo al momento della compilazione e lo mantiene fisso, dynamic
consente al tipo della variabile di cambiare a runtime.
dynamic variabile = 42; // Inizialmente un intero.
print(variabile); // Output: 42
variabile = "Ciao"; // Ora una stringa.
print(variabile); // Output: Ciao
Punti chiave:
- Flessibilità:
dynamic
offre la massima flessibilità, permettendo a una variabile di assumere qualsiasi tipo durante l'esecuzione. - Assenza di Controlli Statici: L'uso di
dynamic
disabilita i controlli di tipo statici del compilatore, il che può portare a errori a runtime se non gestito con attenzione.
Quando Usare dynamic
:
- Interoperabilità: Quando si interagisce con codice che non fornisce informazioni di tipo, come chiamate a librerie esterne o dati JSON non tipizzati.
- Prototipazione Rapida: Durante le fasi iniziali di sviluppo, quando i tipi esatti non sono ancora definiti.
Attenzione: L'uso eccessivo di dynamic
può compromettere la sicurezza e la manutenibilità del codice.
È consigliabile utilizzarlo solo quando strettamente necessario e preferire tipi specifici o l'inferenza dei tipi con var
per beneficiare dei controlli statici del compilatore.
Esercizio 2: Comprendere dynamic
- Dichiara una variabile
dynamic
e assegnale un valore intero. - Cambia il valore della variabile assegnandole una stringa.
- Tenta di chiamare un metodo specifico delle stringhe sulla variabile dopo averle assegnato un intero e osserva cosa accade.
Esercizio 3: Applicazione di var
, final
, const
e dynamic
- Crea una lista di numeri interi utilizzando
var
e aggiungi alcuni elementi. - Dichiara una variabile
final
che contiene una mappa (Map) di coppie chiave-valore, dove le chiavi sono stringhe e i valori sono interi. Prova ad aggiungere una nuova coppia alla mappa. - Definisci una costante
const
che rappresenta il numero massimo di tentativi consentiti in un gioco. - Utilizza una variabile
dynamic
per rappresentare un dato che può essere inizialmente un numero e successivamente una lista.
Conclusione del Capitolo 2
In questo capitolo, abbiamo esplorato come Dart gestisce le variabili e i tipi, distinguendo tra linguaggi a tipizzazione statica e dinamica.
Abbiamo appreso l'uso di var
per l'inferenza dei tipi, e delle parole chiave final
, const
e dynamic
per dichiarare variabili con comportamenti specifici.
Comprendere queste differenze è fondamentale per scrivere codice Dart efficiente, sicuro e manutenibile.
Se hai completato tutti gli esercizi sei pronto per proseguire con il 3° Capitolo.
Se hai invece riscontrato dubbi, non esitare a contattarmi.