Lección 8 · 8 de 20
Enums mejorados · Dart
Dé campos, constructor y métodos a sus enums en Dart y modele con ellos el ciclo de vida de un pedido, con un switch que el compilador comprueba.

Un enum de Dart puede ser mucho más que una lista de nombres: los enums mejorados tienen campos, constructor y métodos. OrderStatus enumera los estados de un pedido, y cada valor lleva su etiqueta (label) y si todavía se puede cancelar (canCancel).
Los valores se escriben arriba, cada uno con sus argumentos, y la lista termina en punto y coma. El constructor tiene que ser `const` y los campos final, porque cada valor es una constante que se crea una sola vez. canCancel es un parámetro con nombre que vale false por defecto, así que solo pending y paid tienen que indicarlo.
El getter next usa una expresión `switch` sobre this para dar el estado siguiente. No lleva un caso _ final: el compilador conoce todos los valores del enum y comprueba que estén cubiertos (delivered || cancelled agrupa dos en un caso). Si mañana se añade un estado, el switch deja de compilar hasta que se trate. isFinal se apoya en next.
En main, el bucle recorre el flujo del pedido hasta que next da null. Todo enum trae además values (la lista de valores), name (su nombre como texto), index (su posición) y values.byName, que convierte un texto en el valor correspondiente: muy útil al leer un estado guardado en JSON o en una base de datos.
Código · main.dart
// An enhanced enum: each value carries data and the enum has methods.enum OrderStatus { pending('Pending', canCancel: true), paid('Paid', canCancel: true), shipped('Shipped'), delivered('Delivered'), cancelled('Cancelled'); const OrderStatus(this.label, {this.canCancel = false}); final String label; final bool canCancel; OrderStatus? get next => switch (this) { pending => paid, paid => shipped, shipped => delivered, delivered || cancelled => null, }; bool get isFinal => next == null;}void main() { OrderStatus? status = OrderStatus.pending; while (status != null) { final flags = '${status.canCancel ? 'can cancel' : 'locked'}, final: ${status.isFinal}'; print('${status.label.padRight(9)} -> $flags'); status = status.next; } print(OrderStatus.values.map((s) => s.name).join(' | ')); final shipped = OrderStatus.values.byName('shipped'); print('${shipped.label} is value number ${shipped.index}');}Salida · dart run main.dart
Pending -> can cancel, final: false Paid -> can cancel, final: false Shipped -> locked, final: false Delivered -> locked, final: true pending | paid | shipped | delivered | cancelled Shipped is value number 2
Para recordar
- Un enum mejorado tiene campos, un constructor
consty métodos. - Cada valor se declara con sus argumentos.
- Un
switchsobre un enum debe cubrir todos sus valores. values,name,indexybyNamevienen incluidos.- Un estado nuevo obliga a revisar cada
switch, y eso evita olvidos.
Ejercicio
Añada un estado returned('Returned') y haga que siga a delivered; el compilador le obligará a tratarlo en el switch de next.