Выбор ответа Middle Dart: типы и null-safety обновлено

Dart: когда выполняется map у Iterable

Вопрос

Сколько раз выведется обработка в этом коде?

final items = [1, 2, 3].map((x) {
  print('обработка');
  return x * 2;
});
print(items.toList().length);
for (final i in items) {}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: 6 раз: map ленивый, toList() и цикл for обходят его заново. map возвращает ленивый Iterable: функция вызывается при обходе, а не при создании. toList() обходит его целиком (3 вызова), for обходит ещё раз (ещё 3).

Варианты ответа

  1. 3 раза: map выполняется сразу при вызове, а дальше обходится готовый результат
  2. 0 раз: без вызова toList() код внутри ленивого map вообще никогда не выполнится
  3. 6 раз: map ленивый, toList() и цикл for обходят его зановоправильный ответ
  4. 3 раза: результат map кешируется после первого обхода, второй обход берёт из кеша

Разбор

map возвращает ленивый Iterable: функция вызывается при обходе, а не при создании. toList() обходит его целиком (3 вызова), for обходит ещё раз (ещё 3). Кеша нет. Если результат нужен несколько раз или в функции есть побочные эффекты, один раз сохраняют .toList() в переменную. Кстати, length у результата map по списку функцию не вызывает: длина берётся у исходного списка.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.