Dart — Genéricos


Los genéricos permiten trabajar con diferentes tipos de datos del lenguaje, buscando más flexibilidad y en ciertas ocasiones evitar duplicidad en el código que implementamos.


Genéricos (Generic)

Los genéricos en Dart se pueden usar en diferentes partes como clases, métodos e interfaces los cuales pueden trabajar con datos generales, el tipo se envía dependiendo de la lógica que se esté implementando. Por convención, la mayoría de las variables de tipo tienen nombres de letra única, como E, T, S, K y V. 

Ya hemos visto estas letras antes en la parte de las colecciones, donde se usan los tipos genéricos ya que pueden recibir cualquier tipo de dato.

class IterableBase<E> {}
class List<E> {}
class Map<K, V> {}
abstract class ExpressionVisitor<R> {
  R visitBinary(BinaryExpression node);
}

¿Por qué usar genéricos?

Los genéricos son usados más que todo por la seguridad de tipo, lo que ayuda a reducir la posibilidad de errores por tipo de dato. también tiene otras ventajas:

  • Reducir la duplicidad de código. Compartiendo una sola interfaz para diferentes implementaciones.
  • Al usarlos correctamente generan un mejor código.
  • El código puede ser más legible y conciso.

Ejemplo

Podríamos tener una interfaz genérica que se encargue de almacenar y consultar información independientemente del tipo de dato.

abstract class Storage<T> {
  void add(T element);
  T get(int index);
}

class ListStorage<T> implements Storage<T> {
  List<T> elements = [];

  @override
  void add(T element) {
    elements.add(element);
  }

  @override
  T get(int index) {
     return elements[index];
  }
}

Literales en colecciones 

Como ya vimos antes los genéricos son usados en las colecciones tanto Listas, Conjuntos y Mapas, los literales de estos son parametrizados, es decir, que antes de generar cualquier colección con literales podemos especificar que tipo de datos queremos para las colecciones.

// ejemplo de List
var numbers = <int>[10, 20, 30];

// ejemplo de Set
var countries = <String>{'Colombia', 'Brasil', 'México'};

// ejemplo de Map
var colors = <int, String>{
1: 'Red',
2: 'Blue',
3: 'Green'
};

Uso en constructores

Para especificar uno o más tipos al usar un constructor, ponga los tipos entre mayor que y menor que (<…>) justo después del nombre de la clase.

var countries = <String>{'Colombia', 'Brasil', 'México'};
var countrySet = Set<String>.of(countries);

var names = Map<int, String>();

Colecciones genéricas y los tipos que contienen

Los tipos genéricos de dardos se ratifican, lo que significa que llevan su información de tipo en tiempo de ejecución, es decir, que no pierden su tipo como si pasa en otros lenguajes.

var colors = <String, String>{'R': 'Red', 'G': 'Green', 'B': 'Blue'};
colors.addAll({'W': 'White', 'O': 'Orange'});
print(colors is Map<String, String>); // true

Métodos genéricos

Los métodos y funciones en Dart como ya dijimos también pueden ser genéricos.

T first<T>(List<T> ts) {
  T tmp = ts[0];
  return tmp;
}

void main() {

  // obtener el valor del porcentaje dado un monto
  var value = getPercentageValue(5, 2000);
  print(value);
}

double getPercentageValue<T extends num>(T percentage, T value) {
  return (percentage * value) / 100 ;
}

Conclusión

Vimos a grandes rasgos lo que son los genéricos en Dart, son bastante útiles más que todo para evitar duplicidad de código, pero tiene muchas más utilidades, espero haya sido útil este contenido para entender un poco de que tratan estos genéricos.

Siguientes pasos

En este aprendizaje diario que estamos realizando de Dart, seguiremos con algo que está dentro de las cosas básicas para luego dar el paso a Flutter, como lo son las Funciones.

Fuentes

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *