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, una forma eficaz de desestructurar e inspeccionar datos en una sola expresión. Los patrones te 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 amplían 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 hacer coincidencias simultáneamente 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',
};
}
void main() {
print(describe(-5)); // Número negativo
print(describe(42)); // Número positivo: 42
print(describe([1, 2, 3])); // List starting with 1
}La cláusula when añade condiciones a los patrones, y ... coincide con los elementos restantes en una list. 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 seguro en cuanto a tipos de estructuras de datos complejas.
Desafío
Fácil¡Construyamos un classifier de data que use la coincidencia de patrones para analizar y categorizar distintos tipos de input! Crearás un sistema que pueda identificar y describe diversas estructuras de data usando las potentes funciones de coincidencia de patrones de Dart 3.
Organizarás tu código en dos archivos:
classifier.dart: Crea una function llamadaclassifyque reciba un parámetroObjecty devuelva una descripciónString. Usa una expresión switch con coincidencia de patrones para gestionar estos casos:- Un list empty
[]debe devolverEmpty list - Un list con exactly un elemento integer debe devolver
Single item: [value] - Un list con exactly dos elements debe devolver
Pair: [first] and [second] - Un list que comienza con un integer seguido de más elements debe devolver
List starting with [first], length: [total length](usa el rest pattern...) - Un map que contenga both las keys
'name'y'age'debe devolver[name] is [age] years old(usa la destructuración de patrones de map) - Un integer que sea negativo (usa la cláusula
when) debe devolverNegative: [value] - Un integer que sea cero debe devolver
Zero - Cualquier otro integer debe devolver
Positive: [value] - Cualquier otro valor debe devolver
Unknown type
- Un list empty
main.dart: Importa tu classifier y demuestra la coincidencia de patrones con varios inputs. Imprime el resultado de clasificar cada uno de estos valores:- Un list empty
[] - Un list con un element:
[42] - Un list con dos elements:
['hello', 'world'] - Un list longer:
[1, 2, 3, 4, 5] - Un map:
{'name': 'Alice', 'age': 25} - El integer
-10 - El integer
0 - El integer
99
- Un list empty
Este desafío combina los patrones de list, los patrones de map, la cláusula when para las guardas y el rest pattern (...) - ¡todas las funciones clave de coincidencia de patrones 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: 99Pruébalo tú mismo
import 'classifier.dart';
void main() {
// TODO: Usa la función classify para categorizar cada valor
// e imprime 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
}
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
1Fundamentos de POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico13Conceptos avanzados de POO
Composición vs. HerenciaMétodos de extensiónClases invocablesClases selladas (Dart 3)Records (Dart 3)Patrones y coincidencia (3.0)Enums con métodos2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón RepositoryPractica por tu cuenta: Compilador de Dart online