Până la apariția versiunii Dart 3.0, returnarea mai multor valori dintr-o funcție presupunea fie definirea unei clase DTO de unică folosință, fie folosirea unor structuri neomogene precum List<dynamic> sau Map<String, dynamic>, care sacrificau complet siguranța tipurilor.
Records rezolvă definitiv această problemă: sunt tipuri compuse anonime, imutabile și tipizate static. Ele permit gruparea facilă a valorilor cu sintaxă concisă de paranteze rotunde, suportă atât câmpuri poziționale cât și câmpuri denumite, și implementează automat egalitatea structurală pe bază de valoare (hashCode și ==).
// Funcție care returnează un Record cu un câmp pozițional și două câmpuri denumite:
(bool isSuccess, {String? errorMessage, int latencyMs}) pingServer(String url) {
// Simulare verificare rețea:
if (url.startsWith('https')) {
return (true, errorMessage: null, latencyMs: 42);
} else {
return (false, errorMessage: 'Protocol nesecurizat', latencyMs: 0);
}
}
void main() {
final result = pingServer('https://dexblog.ro');
// Accesare prin proprietăți poziționale ($1) și denumite:
print('Succes: ${result.$1}');
print('Latență: ${result.latencyMs} ms');
// Destructurare directă a rezultatului:
final (success, :errorMessage, :latencyMs) = pingServer('http://insecure.test');
if (!success) {
print('Conexiune eșuată: $errorMessage');
}
}
Caracteristicile Fundamentale ale Records în Dart
| Proprietate Tehnică | Comportament în Dart 3 | Impact asupra Codului |
|---|---|---|
| Imutabilitate | Toate câmpurile unui Record sunt strict final la runtime. |
Garantează absența efectelor secundare și siguranță în medii concurente. |
| Egalitate Structurală | Două Records cu aceleași valori sunt egale: (1, 'a') == (1, 'a') este true. |
Pot fi utilizate direct ca chei în Map sau elemente în Set fără suprascrierea hashCode. |
| Cost Zero de Definire | Nu necesită fișiere sau clase separate în proiect. | Elimină „boilerplate”-ul excesiv asociat claselor de transfer de date (DTO). |
| Tipizare Completă | Compilatorul cunoaște tipul exact al fiecărui element. | Auto-completare perfectă în IDE și validare completă la compilare AOT. |
void main() {
final pointA = (x: 10, y: 20);
final pointB = (x: 10, y: 20);
final pointC = (x: 15, y: 20);
print(pointA == pointB); // true (aceeași structură și valori!)
print(pointA == pointC); // false
// Utilizare ca element într-un Set (elimină duplicatele automat):
final setOfPoints = {pointA, pointB, pointC};
print(setOfPoints.length); // 2
}