Menu
Coddy logo textTech

Patrones y coincidencia (3.0)

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

Dart 3 introdujo la coincidencia de patrones (pattern matching), una forma poderosa de desestructurar e inspeccionar datos en una sola expresión. Los patrones permiten extraer valores de objetos, comprobar su estructura y vincular variables, todo a la vez.

Ya has visto la desestructuración básica con registros. Los patrones extienden esto para trabajar con objetos, listas y mapas:

void main() {
  // Patrones de lista
  var numbers = [1, 2, 3];
  var [a, b, c] = numbers;
  print('$a, $b, $c');  // 1, 2, 3
  
  // Patrones de mapa
  var user = {'name': 'Alice', 'age': 30};
  var {'name': name, 'age': age} = user;
  print('$name is $age');  // Alice is 30
}

Los patrones se vuelven especialmente potentes en las expresiones switch. Puedes realizar coincidencias por tipo, valor y estructura simultáneamente:

String describe(Object obj) {
  return switch (obj) {
    int n when n < 0 => 'Negative number',
    int n => 'Positive number: $n',
    String s => 'String of length ${s.length}',
    [int first, ...] => 'List starting with $first',
    _ => 'Something else',
  };
}

void main() {
  print(describe(-5));        // Número negativo
  print(describe(42));        // Número positivo: 42
  print(describe([1, 2, 3])); // Lista que comienza con 1
}

La cláusula when añade condiciones a los patrones, y ... coincide con los elementos restantes en una lista. El guion bajo _ actúa como un comodín que coincide con cualquier cosa. Combinados con clases selladas, los patrones permiten un manejo exhaustivo y de tipo seguro de estructuras de datos complejas.

challenge icon

Desafío

Fácil

¡Vamos a construir un clasificador de datos que utilice el emparejamiento de patrones (pattern matching) para analizar y categorizar diferentes tipos de entrada! Crearás un sistema que pueda identificar y describir varias estructuras de datos utilizando las potentes funciones de pattern matching de Dart 3.

Organizarás tu código en dos archivos:

  • classifier.dart: Crea una función llamada classify que reciba un parámetro de tipo Object y devuelva una descripción de tipo String. Utiliza una expresión switch con pattern matching para manejar estos casos:
    • Una lista vacía [] debe devolver 'Empty list'
    • Una lista con exactamente un elemento entero debe devolver 'Single item: $value'
    • Una lista con exactamente dos elementos debe devolver 'Pair: $first and $second'
    • Una lista que comience con un entero seguido de más elementos debe devolver 'List starting with $first, length: ${rest.length + 1}' (utiliza el patrón de resto ...)
    • Un mapa que contenga las claves 'name' y 'age' debe devolver '$name is $age years old' (utiliza la desestructuración de patrones de mapa)
    • Un entero que sea negativo (utiliza la cláusula when) debe devolver 'Negative: $n'
    • Un entero que sea cero debe devolver 'Zero'
    • Cualquier otro entero debe devolver 'Positive: $n'
    • Cualquier otro valor debe devolver 'Unknown type'
  • main.dart: Importa tu clasificador y demuestra el pattern matching con varias entradas. Imprime el resultado de clasificar cada uno de estos valores:
    • Una lista vacía []
    • Una lista con un elemento: [42]
    • Una lista con dos elementos: ['hello', 'world']
    • Una lista más larga: [1, 2, 3, 4, 5]
    • Un mapa: {'name': 'Alice', 'age': 25}
    • El entero -10
    • El entero 0
    • El entero 99

¡Este desafío combina patrones de lista, patrones de mapa, la cláusula when para guardas y el patrón de resto (...), todas las características clave de pattern matching de la lección!

Salida esperada:

Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99

Hoja de referencia

Dart 3 introdujo el pattern matching (coincidencia de patrones) para la desestructuración e inspección de datos en una sola expresión.

Patrones de Listas

Extrae valores de listas:

var numbers = [1, 2, 3];
var [a, b, c] = numbers;
print('$a, $b, $c');  // 1, 2, 3

Patrones de Mapas

Desestructura mapas por clave:

var user = {'name': 'Alice', 'age': 30};
var {'name': name, 'age': age} = user;
print('$name is $age');  // Alice is 30

Expresiones Switch con Patrones

Coincidencia por tipo, valor y estructura:

String describe(Object obj) {
  return switch (obj) {
    int n when n < 0 => 'Negative number',
    int n => 'Positive number: $n',
    String s => 'String of length ${s.length}',
    [int first, ...] => 'List starting with $first',
    _ => 'Something else',
  };
}

Características de los Patrones

  • Cláusula when: Añade condiciones a los patrones
  • ... (patrón de resto): Coincide con los elementos restantes en una lista
  • _ (comodín): Coincide con cualquier cosa

Pruébalo tú mismo

import 'classifier.dart';

void main() {
  // TODO: Usa la función classify para categorizar cada valor
  // y mostrar los resultados
  
  // Prueba con una lista vacía
  print(classify([]));
  
  // TODO: Prueba con una lista que contenga un elemento: [42]
  
  // TODO: Prueba con una lista que contenga dos elementos: ['hello', 'world']
  
  // TODO: Prueba con una lista más larga: [1, 2, 3, 4, 5]
  
  // TODO: Prueba con un map: {'name': 'Alice', 'age': 25}
  
  // TODO: Prueba con el entero -10
  
  // TODO: Prueba con el entero 0
  
  // TODO: Prueba con el entero 99
}
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