Dart è un linguaggio di programmazione di Google, creato appositamente per il framework multipiattaforma Flutter. Combina la compilazione JIT per un ricaricamento a caldo rapidissimo e la compilazione AOT per prestazioni native nelle build di rilascio. Dart è utilizzato non solo nello sviluppo mobile, ma anche per applicazioni web (AngularDart) e soluzioni lato server. Scopri di più sulle capacità del linguaggio nella documentazione ufficiale di Dart.
Punti chiave
Dart è un linguaggio di programmazione con sintassi simile al C, sviluppato da Google sotto la guida di Lars Bak (creatore di Eclipse). La prima versione è stata rilasciata nel 2011, ma Dart ha guadagnato vera popolarità nel 2018 con l'uscita di Flutter 1.0. Il linguaggio è progettato per creare interfacce utente: dispone di supporto integrato per stream, future e pattern reattivi.
La filosofia di Dart è «equilibrio tra prestazioni e produttività». Il linguaggio supporta due strategie di compilazione: JIT (Just-In-Time) per lo sviluppo con ricaricamento a caldo e AOT (Ahead-Of-Time) per build di rilascio con prestazioni native. Il compilatore JIT inietta codice modificato in un'applicazione in esecuzione in millisecondi, senza richiedere la ricompilazione dell'APK — questo è il vantaggio chiave di Dart rispetto ad altri linguaggi nello sviluppo mobile.
Una caratteristica fondamentale di Dart è sound null safety, introdotta in Dart 2.12 (2021). Il sistema di tipi garantisce che una variabile non possa essere null senza dichiarazione esplicita (int?). Ciò elimina NullPointerException in fase di compilazione. Secondo Google, l'adozione di null safety ha ridotto i tassi di crash nelle applicazioni Flutter del 30% in ambienti di produzione.
L'ecosistema Dart comprende tre aree principali: Flutter (applicazioni mobili e desktop), AngularDart (applicazioni web) e Dart Server (soluzioni lato server). Flutter è la piattaforma dominante: secondo Statista (2025), Flutter è utilizzato nel 46% dei progetti mobili multipiattaforma, superando React Native (38%) e Xamarin (8%).
La sintassi di Dart ricorda Java e JavaScript, ma ha le sue costruzioni uniche. Tutto in Dart è un oggetto — anche int, double e bool ereditano da Object. La tipizzazione è opzionale: una variabile dichiarata come var deduce automaticamente il tipo, ma si consiglia di specificare i tipi esplicitamente per leggibilità e prestazioni.
Dart supporta int, double, String, bool, List, Set, Map, Record, Symbol e Runes. Tipo nullable — qualsiasi tipo con suffisso ? (int?, String?). L'operatore ?? (null-aware) restituisce il valore a destra se quello a sinistra è null. La notazione a cascata (..) consente di chiamare più metodi sullo stesso oggetto senza ripetere il riferimento.
// Tipi e dichiarazioni di base in Dart
void main() {
// Tipizzazione esplicita
int age = 25;
double price = 19.99;
String name = 'Dart';
bool isValid = true;
// Null safety — la variabile può essere null
int? nullableAge = null;
int result = nullableAge ?? 0; // Operatore null-aware
// Collezioni con generics
List<String> items = ['Dart', 'Flutter', 'Mobile'];
Map<String, dynamic> config = {
'version': '3.0',
'mode': 'debug',
};
// Notazione a cascata
final list = <String>[]
..add('one')
..add('two')
..sort();
}
// Record — tipo immutabile anonimo
(String, int) user = ('Alice', 30);
print(user.$1); // 'Alice'Il tipo dynamic disabilita il controllo dei tipi — usalo solo quando lavori con JSON o dati dinamici. Record è un nuovo tipo in Dart 3.0 che consente di raggruppare valori senza creare una classe separata. L'operatore null-aware ?? è il modo standard per lavorare con valori nullable, sostituendo lunghe verifiche if-else.
Le classi in Dart — ereditarietà singola (extends), multipla tramite mixin (mixin). Dart non supporta le interfacce come concetto separato — qualsiasi classe può essere implementata (implements). Un mixin è una classe senza costruttore i cui metodi e campi possono essere aggiunti a qualsiasi classe usando la parola chiave with.
// Classi, ereditarietà e mixin in Dart
abstract class Animal {
void sound(); // metodo astratto
}
mixin Swimmer {
void swim() => print('Swimming...');
}
mixin Flyer {
void fly() => print('Flying...');
}
class Duck extends Animal with Swimmer, Flyer {
@override
void sound() => print('Quack!');
}
void main() {
final duck = Duck();
duck.sound(); // Quack!
duck.swim(); // Swimming...
duck.fly(); // Flying...
}
// Costruttore con nome
class Config {
final String env;
Config.development() : env = 'dev';
Config.production() : env = 'prod';
}La classe Duck eredita da Animal e utilizza due mixin — Swimmer e Flyer. Ciò dimostra l'ereditarietà multipla senza problemi di diamante: i mixin vengono risolti linearmente (super chain). I costruttori con nome (Config.development) sono un'alternativa ai metodi factory statici per creare oggetti con parametri preimpostati.
L'asyncronicità in Dart è implementata tramite Future (valore singolo), Stream (sequenza di valori) e async/await. Dart utilizza un modello a thread singolo con un ciclo di eventi, simile a JavaScript, ma con una differenza importante: i calcoli lunghi non bloccano l'UI perché il codice Dart viene eseguito in un Isolate — un thread separato senza memoria condivisa.
Future rappresenta un'operazione asincrona che verrà completata dopo un certo tempo. Un Future può essere in stato di attesa, completato con valore o completato con errore. La catena .then().catchError() è un'alternativa a async/await, ma si consiglia di usare await per leggibilità.
// Caricamento asincrono di dati con Future e Stream
import 'dart:convert';
import 'package:http/http.dart' as http;
class ApiService {
final String baseUrl;
ApiService(this.baseUrl);
// Future per una singola richiesta
Future<Map<String, dynamic>> fetchUser(int id) async {
final response = await http.get(
Uri.parse('$baseUrl/users/$id'),
);
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to load user: ${response.statusCode}');
}
}
// Stream per una sequenza di dati
Stream<int> countStream(int max) async* {
for (var i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
}
void main() async {
final api = ApiService('https://api.example.com');
// Utilizzo di await
final user = await api.fetchUser(1);
print('User: ${user['name']}');
// Elaborazione di Stream con await for
await for (final count in api.countStream(5)) {
print('Count: $count');
}
}La classe ApiService dimostra due tipi di asincronicità: Future per una richiesta HTTP (risposta singola) e Stream per un contatore sequenziale (generatore con async* e yield). Stream è efficace per lavorare con sensori, geolocalizzazione, Firebase Realtime Database — ovunque i dati arrivino continuamente. Isolate utilizza memoria separata — i dati vengono trasmessi tramite SendPort/ReceivePort.
Dart e Flutter formano uno stack unico: Flutter è il framework UI, Dart è il linguaggio di descrizione dell'UI. In Flutter, tutto è un widget — da un pulsante a un'intera applicazione. I widget possono essere stateful (con stato mutabile) e stateless (immutabili). Dart descrive UI dichiarativa: build() restituisce un albero di widget che Flutter renderizza usando Skia (o Impeller su iOS).
Un'applicazione Flutter in Dart consiste in main() → runApp(MyApp()) → MaterialApp. MaterialApp include routing (routes), tema (theme) e localizzazione. Ogni schermata è un Scaffold contenente AppBar, Body (di solito Column/ListView) e BottomNavigationBar. Navigazione tramite Navigator.push/pop o route nominate.
// Applicazione Flutter semplice in Dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dart Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _counter = 0;
void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Dart + Flutter')),
body: Center(
child: Text('Counter: $_counter'),
),
floatingActionButton: FloatingActionButton(
onPressed: _increment,
child: Icon(Icons.add),
),
);
}
}Il widget HomeScreen è un StatefulWidget con stato interno _counter. La chiamata a setState() notifica a Flutter di ricostruire l'UI — il codice Dart riesegue build(), creando un nuovo albero di widget. Flutter confronta (diff) efficientemente l'albero vecchio e quello nuovo, aggiornando solo le parti modificate dello schermo. Hot Reload sostituisce build() senza reimpostare lo stato _counter.
La compilazione di Dart è ibrida: JIT per lo sviluppo e AOT per la produzione. In modalità debug, la Dart VM esegue un compilatore JIT che interpreta il bytecode con possibilità di scambio a caldo del codice. In modalità release, dart compile exe o flutter build crea un binario AOT nativo per un'architettura specifica (arm64, x86_64, armv7).
| Modalità | Compilazione | Velocità di esecuzione | Dimensioni binario | Hot Reload |
|---|---|---|---|---|
| Debug | JIT (VM) | Media | ~50 MB | Sì |
| Release | AOT (Nativo) | Massima | ~15-20 MB | No |
| Web | dart2js | Dipende dal browser | Variabile | Server dev |
La compilazione JIT di Dart in modalità debug fornisce ricaricamento a caldo in ~1 secondo — gli sviluppatori vedono i cambiamenti UI senza perdere lo stato dell'applicazione. La compilazione AOT offre prestazioni vicine alle applicazioni native Swift/Kotlin. Secondo Google, Flutter su Dart AOT raggiunge animazioni a 60 FPS anche su dispositivi di fascia media.
Gli strumenti per sviluppatori Dart includono Dart SDK (compilatore dart, dartanalyzer, dartfmt, pub), Flutter SDK e plugin IDE. Dart SDK viene installato insieme a Flutter SDK nella cartella flutter/bin/cache/dart-sdk. Pub è il gestore di pacchetti che legge pubspec.yaml e scarica le dipendenze da pub.dev.
dart analyze — analizzatore statico che verifica tipi, import non utilizzati ed errori potenziali. dart format — formattatore che formatta automaticamente il codice in uno stile coerente. dart doc — generatore di documentazione dai commenti ///. Flutter DevTools — profiler con ispettore dell'albero dei widget, log, memoria e rete. Dart VM Service — debug di un'applicazione in esecuzione tramite WebSocket.
# pubspec.yaml — configurazione del progetto Dart
name: my_flutter_app
description: A new Flutter project.
version: 1.0.0
environment:
sdk: '>=3.0.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
http: ^1.2.0
provider: ^6.1.0
shared_preferences: ^2.2.0
json_annotation: ^4.8.0
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^2.4.0
json_serializable: ^6.7.0
flutter_lints: ^3.0.0Il file pubspec.yaml descrive le dipendenze di un progetto Dart. Il campo environment:sdk specifica la versione di Dart — la stabile attuale è 3.x. Dependencies sono le librerie principali, dev_dependencies sono per test e generazione di codice. json_annotation + json_serializable generano codice di serializzazione JSON tramite build_runner. flutter_lints è un insieme di regole per l'analizzatore.
Domande frequenti
Dart è un linguaggio di programmazione di Google (2011), progettato per lo sviluppo multipiattaforma con Flutter. Supporta sintassi simile al C, tipizzazione forte, compilazione JIT e AOT. Si caratterizza per sound null safety (da Dart 2.12) e asincronicità attraverso Future e Stream. Utilizzato per applicazioni mobili, web e desktop.
Dart compila in codice nativo (AOT) o JS (dart2js), JavaScript è interpretato. Dart ha una tipizzazione forte con sound null safety, classi integrate e mixin. L'asyncronicità di Dart è basata su Isolate (thread separati senza memoria condivisa), JS — sul ciclo di eventi con Web Workers. Le prestazioni di Dart AOT sono del 30-50% superiori a V8 JIT negli scenari mobili.
Dart compila AOT in codice ARM nativo tramite Dart Native. In modalità debug, Dart VM usa JIT con ricaricamento a caldo. Flutter Engine (C++) renderizza l'UI tramite Skia/Impeller. Per Android — flutter build apk, per iOS — flutter build ios. La build web usa dart2js o dart2wasm. La dimensione dell'APK di rilascio è 15-20 MB (senza divisione AAB).
Dart supporta tipi primitivi: int, double, String, bool. Collezioni: List, Set, Map, Record. Speciali: Symbol, Runes, Null. Tutto è un oggetto, inclusi i primitivi. Null safety: int? permette null, int non è mai null. Operatori ??, ??= per la gestione sicura di null. Generics: List<String>, Map<String, dynamic>.
Flutter SDK include Dart SDK, Flutter Engine e la libreria di widget. IDE — Android Studio o VS Code con plugin Flutter. DevTools — profiler con ispettore di widget. Pub.dev — gestore di pacchetti con oltre 45.000 librerie. Gli strumenti dart analyze e dart format garantiscono la qualità del codice. Build_runner per la generazione di codice di modelli JSON.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche