Volver a la página principal
jueves 31 octubre 2024
9

Cómo usar Generics en Dart

Los Generics en Dart permiten crear clases, métodos y funciones que trabajan con tipos de datos flexibles, manteniendo la seguridad de tipos. Los Generics ayudan a evitar la duplicación de código y a aumentar su reutilización, facilitando la creación de estructuras de datos y funciones que pueden trabajar con diferentes tipos sin perder el tipo fuerte del lenguaje.

¿Qué son los Generics en Dart?

Los Generics permiten definir un "tipo placeholder" en una clase, función o método que luego puede ser reemplazado por cualquier tipo específico al instanciar la clase o llamar al método. Se representan mediante <T>, donde T es el tipo genérico. Por convención, T, K, V, E, o cualquier letra mayúscula se usan como nombres para estos parámetros de tipo.

Sintaxis básica de Generics

Para definir una clase o función genérica, se usa la notación <T> después del nombre de la clase o de la función. Por ejemplo:

class Caja<T> {
  T contenido;

  Caja(this.contenido);

  T obtenerContenido() => contenido;
}

En este ejemplo, Caja es una clase genérica que puede contener cualquier tipo de dato, definido al momento de la instancia.

Ejemplos de uso de Generics en Dart

Crear una clase genérica

A continuación, se muestra una clase Caja que almacena cualquier tipo de valor:

class Caja<T> {
  T contenido;

  Caja(this.contenido);

  T obtenerContenido() => contenido;
}

void main() {
  var cajaDeEnteros = Caja<int>(5);
  print("Contenido de cajaDeEnteros: ${cajaDeEnteros.obtenerContenido()}"); // Imprime: 5

  var cajaDeStrings = Caja<String>("Hola");
  print("Contenido de cajaDeStrings: ${cajaDeStrings.obtenerContenido()}"); // Imprime: Hola
}

Crear funciones genéricas

También puedes definir funciones que acepten o devuelvan valores genéricos:

T retornarPrimero<T>(T a, T b) {
  return a;
}

void main() {
  print(retornarPrimero<int>(3, 5));   // Imprime: 3
  print(retornarPrimero<String>("Hola", "Mundo")); // Imprime: Hola
}

Uso de múltiples tipos genéricos

Puedes definir múltiples tipos genéricos en una clase o función utilizando <T, U, V, ...>:

class Par<T, U> {
  T primero;
  U segundo;

  Par(this.primero, this.segundo);
}

void main() {
  var par = Par<int, String>(1, "uno");
  print("Par: ${par.primero} y ${par.segundo}"); // Imprime: Par: 1 y uno
}

En este caso, la clase Par acepta dos tipos distintos (T y U) para representar dos valores diferentes.

Generics con restricciones de tipo

Es posible restringir los tipos que pueden usarse en un Generic mediante extends. Esto asegura que solo tipos específicos puedan utilizarse como argumentos genéricos.

class CajaNumerica<T extends num> {
  T contenido;

  CajaNumerica(this.contenido);

  T doble() => contenido * 2 as T;
}

void main() {
  var cajaInt = CajaNumerica<int>(5);
  print("Doble: ${cajaInt.doble()}"); // Imprime: Doble: 10

  var cajaDouble = CajaNumerica<double>(2.5);
  print("Doble: ${cajaDouble.doble()}"); // Imprime: Doble: 5.0
}

Aquí, CajaNumerica solo acepta tipos numéricos (int y double), porque el tipo T está restringido con extends num.

Ventajas de usar Generics

  • Seguridad de tipos: Permiten trabajar con tipos específicos sin perder el tipo fuerte de Dart.
  • Reutilización de código: Facilitan la creación de estructuras de datos y funciones flexibles y reutilizables.
  • Eficiencia y mantenibilidad: Ayudan a reducir la duplicación de código y aumentan la legibilidad al especificar claramente el tipo de dato que se espera.

Referencia oficial

Para obtener más información, puedes consultar la documentación oficial de Dart sobre Generics.

Etiquetas:
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer