Расс Кокс публикует новую статью или итераторам быть?
Позавчера Расс выложил новую статью под названием Storing Data in Control Flow, смысл которой сводится к рассуждению о хранении текущих данных внутри горутины, а примеры кода содержат фактически прямую реализацию паттерна «итератор». Те кто давно следят за блогом тех-лида Go компилятора знают, что каждая статья обычно предвещает выход нового предложения по улучшению языка. Так было с vgo (который стал go modules), так было с дженериками, так было с телеметрией в компиляторе. Не всегда эти предложения находят отклик среди сообщества - например предложение по телеметрии пришлось полностью переработать, сменив модель с opt-out на opt-in.
Кто-то спросит - а в чем собственно проблема? А проблем две, в которых вторая вытекает из первой:
1. range
поддерживает только встроенные типы данных (массивы, слайсы, мапы и каналы). Итерацию по собственным типам приходиться делать с помощью создания и вызова методов Next
, Scan
, Iter
. Отсутствие общего паттерна не было большой проблемой до появления дженериков, релиз которых состоялся в Go 1.18. Но вот с их приходом и появлением обобщенных функций для работы с коллекциями (в том числе и в стандартной библиотеке), собственные коллекции данных начинают все больше ощущаться как второсортные. А работа с ними разительно отличается от работы с встроенными коллекциями, что приводит к невозможности, например, создания обобщенного кода для работы со списками и слайсами.
2. Для map
невозможно реализовать итератор стандартными средствами, в отличии от слайсов и каналов, т.к. не существует возможности сохранить нашу текущую позицию в мапе. Безусловно можно воспользоваться пакетом reflect
(а любители темной магии могут подключить unsafe
и скопировать обьявления из стандартной бибилотеки), но эти способы несут проблемы как по удобству, так по безопастности и скорости выполнения. Ситуацию можно решить и через каналы, но скорость подобного кода будет оставлять лучшего, а главное всегда будет существовать риск утечки памяти, если вы забудете закрыть генерирующую горутину.
Запрос на итераторы в open-source сообществе Go и в корпоративных кругах назрел давно. Дискуссия созданная Расс’ом от октября 2022 показывает, что разработчики языка проблему видят и даже имеют варианты решения. А недавняя заметка от разработчиков компилятора показывает, что решение первой проблемы планируют в Go 1.22. Поэтому вполне вероятно, что уже к следующему году нас снова ждет относительно большое обновление языка.
>>Click here to continue<<
