Spread, if y for en colecciones de Dart

Control de flujo y propagación en literales de colecciones

Los literales de List, Set y Map en Dart no son contenedores estáticos; permiten inyectar lógica de control y otros iterables directamente durante su construcción mediante los llamados collection elements. El spread operator ... descompone un Iterable en sus elementos individuales para insertarlos en la nueva colección. El null-aware spread operator ...? es la versión segura que evita errores de ejecución si el iterable es null. Podemos usar if y for dentro de los corchetes para realizar filtrado y transformación de datos de forma declarativa. Esto es fundamental para construir estructuras de datos complejas de una sola pasada, evitando la imperatividad de crear una colección vacía y llenarla mediante llamadas repetitivas a .add(). Si intentas usar el operador ... sobre una variable que es null sin la protección ...?, el programa lanzará una excepción de tipo Null is not a subtype of Iterable.

void main() {
  final roles = ['admin', 'editor'];
  final permissions = ['read', 'write'];
  final extraPermissions = null; // Puede ser null
  final isActive = true;
  final isPremium = false;

  // Construcción declarativa de un log de sesión
  final sessionLog = [
    'SESSION_START',
    ...roles, // Esparce los elementos de 'roles'
    if (isActive) 'STATUS_ACTIVE', // Inserción condicional simple
    if (isPremium) 'LEVEL_PREMIUM' else 'LEVEL_BASIC', // Inserción con else
    ...?extraPermissions, // Spread seguro: si es null, no hace nada
    for (final p in permissions) 'PERM_$p', // Transformación mediante for
  ];

  // Construcción de un mapa de metadatos de usuario
  final metadata = {
    'id': 4521,
    if (isActive) 'status': 'online',
    for (final r in roles) 'role_$r': true, // Iteración directa en Map
  };

  print('Log de sesión: $sessionLog');
  print('Metadatos: $metadata');
}

En el ejemplo anterior, fíjate cómo sessionLog se construye de forma fluida. Al usar ...roles, estamos extrayendo los elementos de la lista original y colocándolos directamente en sessionLog, evitando tener una lista dentro de otra. La instrucción if (isActive) es una inserción condicional: si la condición es falsa, simplemente no se añade nada, lo cual es mucho más limpio que evaluar la condición y llamar a .add(). El uso de if (isPremium) ... else ... permite elegir entre dos elementos posibles para una misma posición lógica.

Con ...?extraPermissions, estamos manejando la nulidad de forma robusta; como la variable es null, el operador ...? simplemente no inserta nada, evitando que la ejecución se detenga. El for (final p in permissions) dentro de la lista es una forma elegante de transformar datos: en lugar de hacer un .map().toList(), realizamos la transformación 'PERM_$p' directamente durante la instanciación. Esto es más eficiente a nivel de memoria porque evita la creación de un Iterable intermedio.

En el Map llamado metadata, el for funciona de forma similar pero asignando pares clave-valor. Cuando escribes for (final r in roles) 'role_$r': true, el compilador está iterando sobre roles y generando dinámicamente las claves del mapa. Bajo el capó, estas estructuras se traducen en una construcción muy eficiente donde la VM puede optimizar la asignación de memoria de la colección desde el inicio, ya que la estructura es declarativa.

El error frecuente

Un error común al trabajar con colecciones es confundir el operador de propagación estándar ... con el null-aware ...? cuando tratas con datos que provienen de fuentes externas (como una API o un JSON) que pueden ser nulas.

// Supongamos que estos datos vienen de un JSON
List<String>? tagsFromApi; 

// Esto causará un error en tiempo de ejecución si tagsFromApi es null
final badList = [...tagsFromApi!]; 

// Esto es la forma correcta y segura
final goodList = [...?tagsFromApi]; 

Si intentas usar ... sobre un valor nulo, el runtime lanzará un error de tipo porque el operador espera un Iterable no nulo para poder iterar sobre él. Siempre que la fuente de tus datos sea opcional o pueda ser null, usa ...?.

36

Dejar un comentario

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

Scroll al inicio