Skip to main content
Records are an anonymous, immutable, aggregate type used to bundle multiple objects into a single object. Unlike class instances, records are structurally typed; a record’s identity and compatibility are determined by the composition of its fields rather than a declared class name.

Syntax and Declaration

Records consist of a comma-delimited list of named or positional fields enclosed in parentheses.

Record Expressions

A record expression creates a record value. Named fields use a colon syntax (name: value), while positional fields are inferred by their order.
// Positional fields only
var positional = ('Dart', 3);

// Named fields only
var named = (name: 'Dart', version: 3);

// Mixed positional and named fields
var mixed = ('Dart', version: 3, beta: false);

Record Type Annotations

Record types are defined by a comma-delimited list of types enclosed in parentheses. Named fields are enclosed inside curly braces {} within the record type annotation.
// Type: (String, int)
(String, int) record1 = ('A', 1);

// Type: ({int x, int y})
({int x, int y}) record2 = (x: 10, y: 20);

// Type: (String, {int age})
(String, {int age}) record3 = ('User', age: 25);

Field Access

Record fields are accessed via built-in getters.
  • Named fields are accessed using the property name (e.g., .x).
  • Positional fields are accessed using the syntax $<position>, starting at $1.
var record = ('first', a: 2, b: true, 'last');

print(record.$1); // 'first'
print(record.a);  // 2
print(record.b);  // true
print(record.$2); // 'last'
Note: Named fields do not have a positional index. In the example above, 'last' is the second positional field, so it is accessed via $2, skipping the named fields.

Structural Typing and Equality

Records have value equality. Two records are considered equal if they have the same shape and their corresponding fields have equal values. The shape of a record is defined solely by:
  1. The number of positional fields.
  2. The names of the named fields.
The runtime types of the fields are not part of the shape definition. For example, (int,) and (double,) share the same shape. Additionally, the order of named fields does not affect the record’s shape or equality.
({int x, int y}) point1 = (x: 1, y: 2);
({int y, int x}) point2 = (y: 2, x: 1);

// True: Shapes match (same named keys) and values match
print(point1 == point2); 

Single-Field Records

To distinguish a record containing a single positional field from a standard parenthesized expression, a trailing comma is required in both the record expression and the type annotation.
var value = (10);   // Type: int
var record = (10,); // Type: (int,)

Destructuring

Records support pattern matching and destructuring, allowing values to be unpacked into local variables.
var (name, age) = ('Alice', 30);
// name is 'Alice', age is 30

var (x: xCoord, y: yCoord) = (x: 10, y: 20);
// xCoord is 10, yCoord is 20
Master Dart with Deep Grasping Methodology!Learn More