Dart este limbajul de programare pe care se bazează Flutter. Este un limbaj cu tipare statică opțională, compilat nativ (AOT - Ahead Of Time pentru producție, JIT - Just In Time pentru dezvoltare, ceea ce face posibil Hot Reload-ul). Sintaxa este familiară oricui a lucrat cu Java, C#, JavaScript sau Kotlin.
Capitol gratuit
Limbajul Dart - esențial
Dart este limbajul de programare pe care se bazează Flutter. Este un limbaj cu tipare statică opțională, compilat nativ (AOT - Ahead Of Time pentru producț...
Introducere
Variabile și tipuri de date
// Tip explicit
String nume = 'Andrei';
int varsta = 28;
double pret = 149.99;
bool esteActiv = true;
// Inferență de tip cu var
var oras = 'București'; // Dart deduce automat: String
// Constante
final DateTime dataCreare = DateTime.now(); // se calculează o dată, la runtime
const double tvaProcent = 19.0; // valoare fixă, la compilare
// Tip dinamic (evitați dacă se poate)
dynamic oricare = 'text';
oricare = 42; // permis, dar pierdeți siguranța de tipNull safety
Din Dart 3, null safety este obligatorie în orice proiect nou. O variabilă nu poate fi null decât dacă tipul ei este marcat explicit cu ?.
String numeObligatoriu = 'Maria'; // nu poate fi null niciodată
String? numeOptional; // poate fi null
// Operatorul ?? oferă o valoare implicită dacă expresia e null
String afisare = numeOptional ?? 'Fără nume';
// Operatorul ?. apelează metoda doar dacă obiectul nu e null
int? lungime = numeOptional?.length;
// Operatorul ! (bang) - "sunt sigur că nu e null" (folosiți cu grijă!)
String numeSigur = numeOptional!;
// Atribuire condiționată
numeOptional ??= 'Valoare implicită';
Atenție: Operatorul
! aruncă o excepție la runtime dacă valoarea este de fapt null. Folosiți-l doar când sunteți absolut sigur, sau preferați verificări explicite cu if (variabila != null).
Funcții
// Funcție simplă
int aduna(int a, int b) {
return a + b;
}
// Sintaxă arrow pentru funcții cu o singură expresie
int inmulteste(int a, int b) => a * b;
// Parametri opționali cu valoare implicită (named parameters)
void salutare({String nume = 'Vizitator', bool formal = false}) {
print(formal ? 'Bună ziua, $nume!' : 'Salut, $nume!');
}
salutare(nume: 'Ioana', formal: true);
// Parametri obligatorii denumiți
void creeazaUtilizator({required String email, required String parola}) {
// ...
}
// Funcții ca parametri (higher-order functions)
void proceseaza(List numere, int Function(int) transformare) {
for (var n in numere) {
print(transformare(n));
}
}
proceseaza([1, 2, 3], (n) => n * n); Clase și obiecte
class Produs {
final String nume;
final double pret;
bool inStoc;
// Constructor
Produs({required this.nume, required this.pret, this.inStoc = true});
// Constructor numit
Produs.faraStoc(this.nume, this.pret) : inStoc = false;
// Metodă
String descriere() {
return '$nume - ${pret.toStringAsFixed(2)} lei';
}
// Getter calculat
String get status => inStoc ? 'Disponibil' : 'Stoc epuizat';
}
// Moștenire
class ProdusReducere extends Produs {
final double procentReducere;
ProdusReducere({
required super.nume,
required super.pret,
required this.procentReducere,
});
double get pretFinal => pret * (1 - procentReducere / 100);
}
void main() {
final produs = Produs(nume: 'Cască wireless', pret: 249.99);
print(produs.descriere());
print(produs.status);
}Colecții (List, Map, Set)
// List - listă ordonată
List orase = ['București', 'Cluj-Napoca', 'Iași'];
orase.add('Timișoara');
final primulOras = orase.first;
// Map - perechi cheie-valoare
Map stocProduse = {
'telefon': 12,
'laptop': 5,
};
stocProduse['tabletă'] = 8;
// Set - elemente unice, fără duplicate
Set categorii = {'electronice', 'mobilier', 'electronice'};
print(categorii.length); // 2, duplicatul e eliminat automat
// Operații funcționale utile
final numereMari = [1, 5, 12, 3, 20]
.where((n) => n > 4)
.map((n) => n * 2)
.toList();
// rezultat: [10, 24, 40] Programare asincronă - Future, async/await, Stream
Operațiile care durează (cereri de rețea, citire fișiere, baze de date) sunt asincrone în Dart, prin tipul Future.
Future descarcaDate() async {
await Future.delayed(const Duration(seconds: 2)); // simulează o cerere
return 'Date primite de la server';
}
void afiseazaDate() async {
print('Se încarcă...');
final rezultat = await descarcaDate();
print(rezultat);
}
// Gestionarea erorilor cu try/catch
Future incarcaSigur() async {
try {
final date = await descarcaDate();
print(date);
} catch (eroare) {
print('A apărut o eroare: $eroare');
} finally {
print('Operațiune finalizată');
}
}
// Stream - un flux de valori care sosesc în timp (ex: actualizări live)
Stream numaraSecunde() async* {
for (int i = 1; i <= 5; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i;
}
}
void ascultaStream() {
numaraSecunde().listen((valoare) {
print('Secunda: $valoare');
});
} Operatori utili specifici Dart
| Operator | Rol | Exemplu |
|---|---|---|
?? | Valoare implicită dacă e null | nume ?? 'Anonim' |
?. | Apel sigur pe obiect posibil null | utilizator?.email |
??= | Atribuie doar dacă e null | total ??= 0 |
.. (cascade) | Apeluri multiple pe același obiect | lista..add(1)..add(2) |
is / as | Verificare / conversie de tip | if (obiect is String) |
... (spread) | Extinde o colecție în alta | [...lista1, ...lista2] |
Sfat: Dacă veniți din JavaScript, TypeScript sau Kotlin, majoritatea conceptelor Dart vă vor părea familiare. Cea mai mare diferență de mentalitate este obligativitatea null safety, care previne o clasă întreagă de erori la runtime încă din faza de scriere a codului.
Continuați cu restul cursului
Acesta este capitolul 3 din cele 14 ale cursului, cu 8 lecții din 85. Cumpărați cursul și parcurgeți tot conținutul în cont, cu progres salvat, test final și certificat.
Cumpărați cursul la 130 €