पाठ 13 / 25

Records and Destructuring

Group values with records and unpack them with destructuring.

Lightweight anonymous data

Records (Dart 3) are anonymous, immutable aggregates of values, ideal for returning several values from a function without defining a class. They can have positional fields ((String, int), accessed as $1, $2) and named fields (({String name, int age}), accessed by name), or both. Records have structural equality: two records with the same shape and equal values are ==, and their hashCode matches, so they work as map keys. Their type is part of the signature: (double lat, double lng) location(). Destructuring unpacks records and other values with patterns: final (lat, lng) = location(); or final (:name, :age) = person; (the :name shorthand binds a variable with the field's name). Records pair naturally with for loops over indexed or map entries. Use records for small, local groupings; once a group of values gets a name, behaviour or is used widely, promote it to a class.

A record as a labelled bundle

A record bundles a few values together without declaring a class, and destructuring unpacks them.

A small parcel with two or three tagged compartments, and arrows splitting the parcel into separate labelled items.
Figure 5.1 — Creating and destructuring a record.

Returning and destructuring records

Several return values without a helper class.

(double min, double max, double average) stats(List<double> values) {
  final sum = values.fold<double>(0, (a, b) => a + b);
  final sorted = values.toList()..sort();
  return (sorted.first, sorted.last, sum / values.length);
}

({String city, int pinCode}) parseAddress(String text) {
  final parts = text.split(',');
  return (city: parts[0].trim(), pinCode: int.parse(parts[1].trim()));
}

void main() {
  final (min, max, avg) = stats([72, 45, 90, 38]);
  print('min $min, max $max, avg $avg');           // min 38.0, max 90.0, avg 61.25

  final (:city, :pinCode) = parseAddress('Pune, 411001');
  print('$city $pinCode');

  final a = (x: 1, y: 2);
  final b = (x: 1, y: 2);
  print(a == b);                                   // true: structural equality

  final scores = {'Asha': 91, 'Ravi': 64};
  for (final MapEntry(:key, :value) in scores.entries) {
    print('$key scored $value');
  }
}

Name fields when meaning is not obvious

(double, double) could be latitude and longitude or width and height. Named fields such as ({double lat, double lng}) make call sites self-explanatory at almost no cost.

त्वरित जाँच: How do records compare for equality in Dart?

  • Structurally: same shape and equal field values means equal
  • By identity only
  • They cannot be compared
  • Only by their first field
Answer

Structurally: same shape and equal field values means equal — Records have structural equality and matching hash codes.