Menu
Coddy logo textTech

Records (Dart 3)

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 86 de 110.

Dart 3 introdujo los records: una forma ligera de agrupar múltiples valores sin necesidad de crear una clase completa. Los records son inmutables, tienen igualdad incorporada y son perfectos para devolver múltiples valores desde una función o agrupar datos relacionados de forma temporal.

Crea un registro envolviendo los valores entre paréntesis:

void main() {
  // Un registro simple con dos valores
  var point = (10, 20);
  print(point.$1);  // 10 - accede al primer elemento
  print(point.$2);  // 20 - accede al segundo elemento
  
  // Registros con campos con nombre
  var person = (name: 'Alice', age: 30);
  print(person.name);  // Alice
  print(person.age);   // 30
}

Se accede a los campos posicionales con $1, $2, etc., mientras que los campos con nombre utilizan sus nombres directamente. Puedes mezclar ambos estilos en un solo registro.

Los registros destacan al devolver múltiples valores desde funciones; no es necesario crear una clase solo para devolver dos fragmentos de datos:

(int, int) divideWithRemainder(int a, int b) {
  return (a ~/ b, a % b);
}

(String name, int age) getUser() {
  return ('Bob', 25);
}

void main() {
  var (quotient, remainder) = divideWithRemainder(17, 5);
  print('$quotient remainder $remainder');  // 3 residuo 2
  
  var (name, age) = getUser();
  print('$name is $age');  // Bob is 25
}

Los registros admiten automáticamente la igualdad basada en sus valores, lo que los hace convenientes para realizar comparaciones sin tener que implementar == por tu cuenta. Usa registros cuando necesites agrupaciones de datos simples e inmutables; usa clases cuando necesites métodos, mutabilidad o un comportamiento más complejo.

challenge icon

Desafío

Fácil

¡Vamos a construir un sistema de coordenadas usando records! Crearás funciones que trabajen con puntos 2D representados como records, demostrando cómo los records facilitan devolver y trabajar con múltiples valores relacionados sin necesidad de crear clases completas.

Organizarás tu código en dos archivos:

  • geometry.dart: Crea funciones que utilicen records para trabajar con datos de coordenadas:
    • Una función createPoint(int x, int y) que devuelva un record con campos nombrados x e y. El tipo de retorno debe ser ({int x, int y})
    • Una función midpoint(({int x, int y}) p1, ({int x, int y}) p2) que calcule y devuelva el punto medio entre dos puntos como un record con campos nombrados. Usa la división entera (~/) para el cálculo
    • Una función distance(({int x, int y}) p1, ({int x, int y}) p2) que devuelva un record con campos posicionales: la distancia horizontal (diferencia en x) y la distancia vertical (diferencia en y). El tipo de retorno debe ser (int, int). Calcúlalo como p2.x - p1.x y p2.y - p1.y
  • main.dart: Importa tu archivo de geometría y demuestra los records en acción:
    • Crea dos puntos usando createPoint: el punto A en (2, 4) y el punto B en (10, 8)
    • Imprime 'Point A: (${pointA.x}, ${pointA.y})' usando los campos nombrados
    • Imprime 'Point B: (${pointB.x}, ${pointB.y})' usando los campos nombrados
    • Calcula el punto medio e imprime 'Midpoint: (${mid.x}, ${mid.y})'
    • Calcula la distancia y usa la desestructuración para extraer los valores en las variables dx y dy, luego imprime 'Distance: dx=$dx, dy=$dy'

¡Observa cómo los records te permiten devolver múltiples valores de forma limpia: campos nombrados para mayor claridad cuando el significado importa, y campos posicionales cuando el contexto es obvio!

Salida esperada:

Point A: (2, 4)
Point B: (10, 8)
Midpoint: (6, 6)
Distance: dx=8, dy=4

Hoja de referencia

Dart 3 introdujo los records (registros): una forma ligera de agrupar múltiples valores sin crear una clase completa. Los records son inmutables y perfectos para devolver múltiples valores desde una función.

Crea un record envolviendo los valores entre paréntesis:

// Record simple con campos posicionales
var point = (10, 20);
print(point.$1);  // 10 - accede al primer elemento
print(point.$2);  // 20 - accede al segundo elemento

// Records con campos con nombre
var person = (name: 'Alice', age: 30);
print(person.name);  // Alice
print(person.age);   // 30

Se accede a los campos posicionales con $1, $2, etc., mientras que los campos con nombre utilizan sus nombres directamente.

Los records son ideales para devolver múltiples valores desde funciones:

// El tipo de retorno especifica la estructura del record
(int, int) divideWithRemainder(int a, int b) {
  return (a ~/ b, a % b);
}

// Campos con nombre en el tipo de retorno
(String name, int age) getUser() {
  return ('Bob', 25);
}

// Desestructuración de records
var (quotient, remainder) = divideWithRemainder(17, 5);
print('$quotient remainder $remainder');  // 3 remainder 2

var (name, age) = getUser();
print('$name is $age');  // Bob is 25

Los tipos de retorno de record con campos con nombre utilizan llaves:

({int x, int y}) createPoint(int x, int y) {
  return (x: x, y: y);
}

Los records admiten automáticamente la igualdad basada en sus valores.

Pruébalo tú mismo

import 'geometry.dart';

void main() {
  // TODO: Crear el punto A en (2, 4) usando createPoint
  
  // TODO: Crear el punto B en (10, 8) usando createPoint
  
  // TODO: Imprimir el Punto A usando campos con nombre: Point A: ([x], [y])
  
  // TODO: Imprimir el Punto B usando campos con nombre: Point B: ([x], [y])
  
  // TODO: Calcular el punto medio e imprimir: Midpoint: ([x], [y])
  
  // TODO: Calcular la distancia y usar la desestructuración para extraer en dx y dy
  // Luego imprimir: Distance: dx=[dx], dy=[dy]
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos