Dart 3 Records y Patterns en Flutter: ejercicio resuelto
Dart 3 Records y Patterns en Flutter: ejercicio resuelto
Dart 3 incorporó tres grandes novedades de lenguaje: records (structs anónimos con tipado estático), patterns (desestructuración y pattern matching) y sealed classes (jerarquías cerradas que habilitan exhaustividad). Juntas transforman cómo se modela el estado y la lógica de negocio en Flutter.
Enunciado
Implementa una mini-app que demuestre las tres características:
- Records: función que devuelve un record con nombre, precio y stock.
- Pattern matching con switch expression: función
area()que acepta distintas formas. - Sealed classes:
LoadState<T>para modelar estado async (Loading,Success,Failure). - List & map patterns: destructuring de listas y mapas.
- Muestra todos los ejemplos en una pantalla con
ListViewdeCard.
Dependencias
Solo Dart 3 — ya incluido en Flutter 3.10+. Sin dependencias extra.
Solución completa
Conceptos clave
| Concepto | Detalle |
|---|---|
(A, B) | Record posicional; acceso con $1, $2 o destructuring (var a, var b) = rec |
({String name, int age}) | Record con campos nombrados; acceso con .name, .age |
sealed class | Clase cerrada: solo subclases en el mismo archivo. Permite exhaustividad en switch |
switch expression | Expresión (no statement) que devuelve un valor; el compilador exige cubrir todos los casos con sealed |
:var field | Object pattern nombrado: extrae field del objeto sin repetir el nombre |
[first, ..., last] | List rest pattern: captura primer y último elemento, ignora el medio |
{'key': var v} | Map pattern: extrae el valor de la clave 'key' |
Errores frecuentes
switchno exhaustivo: con sealed classes, el compilador emite un warning si falta algún subtipo. Añade un caso_solo si realmente hay un caso default válido.- Records vs clases: los records son inmutables y no tienen métodos propios. Para lógica de negocio, una clase sigue siendo mejor. Los records brillan en retornos múltiples y datos temporales.
$1vs.fieldName: los records posicionales usan$1,$2…; los records con nombre usan.fieldName. Mezclarlos da error de compilación.- Flutter < 3.10: Dart 3 requiere Flutter 3.10+. Verifica con
flutter --version.
Aplicación práctica
- Retorno múltiple:
(String, int) parseVersion(String v)evita crear clases wrapper. - Estado async:
LoadState<T>sealed es un patrón muy limpio que reemplaza múltiples booleans (isLoading,hasError). - Pattern matching en Navigator:
switch (route)con sealed classes para routing type-safe. - Riverpod + sealed: combinado con
@riverpod,AsyncValueusa el mismo patrón internamente.
Siguiente ejercicio recomendado
- Riverpod en Flutter: ejercicio resuelto
- Flutter Widget Test: ejercicio resuelto
- Todos los ejercicios de Flutter
Práctica guiada y siguiente paso
- Más ejercicios de Flutter
- Ejercicios C para reforzar fundamentos
- Programación en C en 100 ejercicios resueltos
- Ver en Amazon (incluido en Kindle Unlimited)
FAQ
¿Los records reemplazan a las clases en Dart 3?
No. Los records son para datos temporales, retornos múltiples y composición simple. Las clases siguen siendo mejores cuando necesitas métodos, herencia, igualdad personalizada (aunque los records tienen igualdad estructural automática) o serialización JSON compleja.
¿Qué diferencia hay entre switch statement y switch expression?
El switch expression (con =>) devuelve un valor y es más conciso. El switch statement (con { case: break; }) ejecuta código. Con Dart 3, el expression es preferible para mapear valores; el statement para ejecutar side effects.
¿Los sealed classes son como enums?
Son complementarios. Los enums son para conjuntos de valores constantes simples. Las sealed classes son para jerarquías de tipos donde cada subtipo puede tener sus propios campos. LoadState<T> con Success(data) y Failure(message) no sería posible con un enum.