Answer
Overview
Dart Records (introduced in Dart 3.0) are anonymous immutable composite types — they bundle multiple values together without defining a full class. Think of them as lightweight, named tuples.
Basic Record Syntax
dart// Positional record (int, String) person = (28, 'Alice'); print(person.$1); // 28 ← First field print(person.$2); // Alice ← Second field // Named record (recommended) ({String name, int age}) user = (name: 'Alice', age: 28); print(user.name); // Alice print(user.age); // 28 // Mixed (int, {String name}) mixed = (1, name: 'Bob'); print(mixed.$1); // 1 print(mixed.name); // Bob
Records as Return Types (Key Use Case)
Before records, you needed a class or List to return multiple values:
dart// ❌ Old way — need a Map or class Map<String, dynamic> fetchUser() { return {'user': user, 'token': token}; } // ✅ Record — type-safe multiple return values (User, String) fetchUserAndToken() { return (currentUser, authToken); } // Destructure on use final (user, token) = fetchUserAndToken(); print(user.name); // Alice print(token); // Bearer xyz... // Named record — more readable ({User user, String token}) login() { return (user: currentUser, token: authToken); } final result = login(); print(result.user.name); print(result.token);
Record Features
dart// Records are equal if all fields are equal final r1 = (1, 'Alice'); final r2 = (1, 'Alice'); print(r1 == r2); // true ✅ (unlike class instances) // Records are immutable — no field mutation ({String name, int age}) rec = (name: 'Bob', age: 30); // rec.name = 'Alice'; // ❌ Not allowed // Pattern matching with records (Dart 3) switch (rec) { case (name: final n, age: final a) when a > 18: print('Adult: $n'); }
Typedef for Reusable Record Types
darttypedef Coordinate = (double lat, double lng); Coordinate getLocation() => (12.9716, 77.5946); final (lat, lng) = getLocation(); print('$lat, $lng'); // 12.9716, 77.5946
Records vs Classes vs Maps
| Feature | Record | Class | Map |
|---|---|---|---|
| Type safety | ✅ | ✅ | ❌ |
| Immutable | ✅ Always | Depends | ❌ |
| Named fields | ✅ | ✅ | String keys |
| Equality | ✅ Value-based | ❌ Ref-based | ✅ |
| Methods | ❌ | ✅ | ❌ |
| Boilerplate | ✅ None | ❌ High | ✅ Low |
Best Use Case: Return multiple typed values from a function without creating a full class. Use named records for clarity.