Генераторы

Фанат

oncle terrible
Команда форума
Рассудите, братцы.
Я тут залез на тропу войнушки, и очень хочу понять, где я туплю.

Началось всё с утверждения, Известно, что генераторы нужны для оптимизации потребления памяти при обработке больших массивов.
Я уже тогда залез в 11 комнату с вопросами, но на меня внимания не обратили.
А в последние дни вылезло это и это
И тут я не выдержал и полез со своими правками в мануал.
И снова был непонят.

Кто здесь неправ?
Я совсем туплю, или просто не могу нормально донести свою мысль?
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Генераторы конечно, не нужны для уменьшения потребления памяти при обходе массивов. Генераторы - это просто функции, хранящие состояние, которые реализуют интерфейс итератора.
Хранить состояние при обходе больших данных можно прекрасно и без генератора, просто генератор проще переиспользовать.
 

Фанат

oncle terrible
Команда форума
Блин, шикарно сформулировано.
Наверное вот прямо в таком виде и надо в мануале написать.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я что-то помню насчет того, что генераторы просто немного быстрее, чем foreach, но это просто охота за дофамином, к целям коммерческой разработки это не имеет отношения
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Строго говоря, в пхп генераторы чуть сложнее, на их состояние можно влиять извне, передавая им данные (на практике я такого не видел практически в использовании) и они могли бы использоваться в композиции функций, особенно теперь, когда 8.1 вышел, но к сожалению, важные функции типа array_map, array_filter принимают только массивы, а не итераторы.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
А, ну еще можно В генератор потреблять данные, через обратный yield, но опять таки, в пхп смысла в этом немного было, с 8.1 может больше смысла будет
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
реальный пример использования генераторов с передачей в них данных - amphp
 

AnrDaemon

Продвинутый новичок
И тут я не выдержал и полез со своими правками в мануал.
Проблема в том, что ты использовал array, в то время как генератор возвращает Iterator.
Соответственно, генератор не может использоваться там, где требуется именно array. Даже Traversable не везде принимается, как выше было сказано.
Думаю, самым простым определением будет "генератор - это функция, создающая итератор". Дальше можно уточнять до посинения, но смысл послания от этого не изменится.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
генератор не создает итератор
создает, потому что у слова "генератор" два значения - функция и класс,
получается, что функция-генератор создает класс-генератор, который реализует интерфейс Iterator
Any function containing yield is a generator function.
When a generator function is called, it returns an object that can be iterated over.
 

WMix

герр M:)ller
Партнер клуба
и генератор и итератор это https://www.php.net/manual/ru/class.traversable

Код:
php > function a(){
php { yield 42;
php { }
php > $g = a();
php > var_dump($g);
object(Generator)#1 (0) {
}
php > var_dump($g instanceof Traversable);
bool(true)
php > var_dump($g instanceof Iterator);
bool(true) // для меня было новым, вроде раньше проверял
php >
 
Последнее редактирование:
Сверху