Dart: Enums, Extension Methods y Records
Tres características que hacen a Dart más expresivo que un enum tradicional
🪐 1. Enhanced Enum (con datos y métodos)
Resultado:
Elige un planeta
enum Planeta {
mercurio(gravedad: 0.378),
marte(gravedad: 0.377),
jupiter(gravedad: 2.360),
neptuno(gravedad: 1.140);
const Planeta({required this.gravedad});
final double gravedad;
double pesoEn(double pesoTierra) => pesoTierra * gravedad;
}
print(Planeta.jupiter.pesoEn(70)); // 165.2
💡 Enhanced enums (Dart 2.17+)
Antes, un enum de Dart solo era una lista de valores. Ahora puede tener constructor, propiedades y métodos, como una clase normal — perfecto para modelar catálogos de valores fijos con comportamiento (estados de un pedido, tipos de suscripción, etc.).
🧩 2. Extension Methods
Resultado:
Prueba un número
extension NumeroUtil on int {
bool get esPar => this % 2 == 0;
bool get esPrimo {
if (this < 2) return false;
for (int i = 2; i <= this ~/ 2; i++) {
if (this % i == 0) return false;
}
return true;
}
}
print(7.esPar); // falseprint(7.esPrimo); // true
💡 ¿Para qué sirven?
Las extension añaden métodos/getters a un tipo que ya existe (incluso int, String o widgets de Flutter que no puedes modificar), sin tener que heredar de él ni envolverlo en otra clase.
📦 3. Records y Patterns (Dart 3)
Resultado:
Construye un record
(String, int) persona() => ('Marta', 20);
// Destructuring: extraer los valores del recordfinal (nombre, edad) = persona();
String clasificar((String, int) p) => switch (p) {
(_, int e) when e < 13 => 'niño/a',
(_, int e) when e < 18 => 'adolescente',
(_, int e) when e < 65 => 'adulto/a',
_ => 'jubilado/a',
};
print(clasificar(persona())); //
💡 Records
Un record ((String, int)) te permite devolver varios valores desde una función sin tener que crear una clase solo para eso. Combinado con switch y patterns, puedes "desestructurar" y examinar su contenido de forma muy compacta.
🎯 Conceptos Clave
Enhanced enums
- Constructor, propiedades, métodos
- Cada valor es una instancia const
Extension methods
extension X on Tipo { ... }- Añade funciones sin heredar
Records & Patterns
(Tipo1, Tipo2)agrupa valoresswitch+ patterns para desestructurar
💪 Ejercicio Práctico
Combina las tres características
- Añade un valor
tierra(gravedad: 1.0)al enumPlaneta. - Crea una extension
on Stringcon un getteresPalindromo. - Crea una función que devuelva un record
(double x, double y)representando un punto, y clasifícalo por cuadrante conswitch.
Solución 1
enum Planeta {
tierra(gravedad: 1.0),
// ...resto de planetas ;
const Planeta({required this.gravedad});
final double gravedad;
}
Solución 2
extension PalindromoUtil on String {
bool get esPalindromo => this == split('').reversed.join('');
}
Solución 3
String cuadrante((double, double) punto) => switch (punto) {
(> 0, > 0) => t('Cuadrante I'),
(< 0, > 0) => t('Cuadrante II'),
(< 0, < 0) => t('Cuadrante III'),
(> 0, < 0) => t('Cuadrante IV'),
_ => t('Sobre un eje'),
};