Els generadors són una característica poderosa en Dart que permet crear iteradors de manera fàcil i eficient. Els generadors són funcions que poden pausar la seva execució i retornar múltiples valors al llarg del temps, en lloc de retornar un únic valor com les funcions normals. Això és especialment útil quan es treballa amb col·leccions grans o seqüències infinites, ja que permet processar elements un a un sense necessitat de carregar tota la col·lecció a la memòria.

Conceptes Clau

  1. Funcions Generadores: Són funcions que utilitzen la paraula clau yield per retornar valors de manera seqüencial.
  2. Generadors Asíncrons: Són funcions generadores que utilitzen async* i yield per treballar amb valors asíncrons.
  3. Iteració: Els generadors es poden iterar utilitzant bucles for o altres mecanismes d'iteració.

Funcions Generadores

Una funció generadora és una funció que retorna un iterador. Utilitza la paraula clau yield per retornar valors un a un.

Exemple de Funció Generadora

Iterable<int> generadorDeNumeros(int finsA) sync* {
  for (int i = 0; i <= finsA; i++) {
    yield i;
  }
}

void main() {
  var numeros = generadorDeNumeros(5);
  for (var numero in numeros) {
    print(numero);
  }
}

Explicació:

  • La funció generadorDeNumeros és una funció generadora que retorna un iterador d'enters.
  • Utilitza sync* per indicar que és una funció generadora síncrona.
  • La paraula clau yield s'utilitza per retornar cada número de l'iterador.
  • En el main, iterem sobre els números generats i els imprimim.

Generadors Asíncrons

Els generadors asíncrons són útils quan es treballa amb operacions asíncrones, com ara crides a API o operacions de lectura/escriptura de fitxers.

Exemple de Generador Asíncron

Stream<int> generadorDeNumerosAsincron(int finsA) async* {
  for (int i = 0; i <= finsA; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

void main() async {
  var numeros = generadorDeNumerosAsincron(5);
  await for (var numero in numeros) {
    print(numero);
  }
}

Explicació:

  • La funció generadorDeNumerosAsincron és una funció generadora asíncrona que retorna un Stream d'enters.
  • Utilitza async* per indicar que és una funció generadora asíncrona.
  • La paraula clau yield s'utilitza per retornar cada número de l'iterador.
  • En el main, utilitzem await for per iterar sobre els números generats de manera asíncrona i imprimir-los.

Exercicis Pràctics

Exercici 1: Generador de Nombres Parells

Crea una funció generadora que retorni tots els nombres parells fins a un número donat.

Iterable<int> generadorDeParells(int finsA) sync* {
  for (int i = 0; i <= finsA; i++) {
    if (i % 2 == 0) {
      yield i;
    }
  }
}

void main() {
  var parells = generadorDeParells(10);
  for (var parell in parells) {
    print(parell);
  }
}

Exercici 2: Generador Asíncron de Fibonacci

Crea una funció generadora asíncrona que retorni els primers n números de la seqüència de Fibonacci.

Stream<int> generadorDeFibonacci(int n) async* {
  int a = 0, b = 1;
  for (int i = 0; i < n; i++) {
    await Future.delayed(Duration(milliseconds: 500));
    yield a;
    int temp = a;
    a = b;
    b = temp + b;
  }
}

void main() async {
  var fibonacci = generadorDeFibonacci(10);
  await for (var numero in fibonacci) {
    print(numero);
  }
}

Errors Comuns i Consells

  • Oblidar el sync* o async*: Assegura't d'utilitzar sync* per a generadors síncrons i async* per a generadors asíncrons.
  • No utilitzar await en generadors asíncrons: Quan utilitzis generadors asíncrons, recorda utilitzar await per esperar operacions asíncrones.
  • Iteració incorrecta: Utilitza for per iterar sobre generadors síncrons i await for per iterar sobre generadors asíncrons.

Conclusió

Els generadors són una eina poderosa en Dart per treballar amb seqüències de dades de manera eficient. Tant els generadors síncrons com els asíncrons permeten crear iteradors que poden retornar múltiples valors al llarg del temps, facilitant el treball amb col·leccions grans o operacions asíncrones. Practica amb els exemples i exercicis proporcionats per dominar l'ús dels generadors en Dart.

© Copyright 2024. Tots els drets reservats