Кіріспе

Компьютерлік ғылымда генератор – циклдың итерациялық мінез-құлқын басқаруға қолданылатын процедура. Барлық генераторлар сонымен қатар итераторлар болып табылады. Генератор массивті қайтаратын функцияға өте ұқсас, оның параметрлері бар, оны шақыруға болады және мәндер тізбегін жасайды. Дегенмен, барлық мәндерді қамтитын массив құрып, оларды бірден қайтарудың орнына, генератор мәндерді біртіндеп шығарып береді, бұл аз жадты қажет етеді және шақырушыға алғашқы бірнеше мәндерді дереу өңдеуге мүмкіндік береді. Қысқасы, генератор функция сияқты көрінеді, бірақ итератор сияқты жұмыс істейді. Генераторларды корутиналар немесе бірінші дәрежелі жалғаулар сияқты күштірек басқару ағыны құрылымдары арқылы жүзеге асыруға болады. Генераторлар, жартылай корутиналар деп те аталады, корутиналардың ерекше жағдайы (және одан әлсіз), себебі олар әрқашан шақырушыға басқаруды қайтарады (мәнді қайтарғанда), корутинаға секіруді көрсетудің орнына; корутиналар мен генераторларды салыстыруға қараңыз.

Қолданылуы

Генераторлар әдетте циклдер ішінде шақырылады. Генераторды циклде алғаш рет кездестіргенде, итератор нысаны құрылады, ол генератордың бастапқы күйін және сәйкес параметрлерге байланысты аргументтерді қамтиды. Генератордың коды арнайы yield әрекетіне кездескенше осы итератордың контекстінде орындалады; сол кезде yield әрекетімен берілген мән шақыру өрнегінің мәні ретінде қолданылады. Келесі рет келесі итерацияда сол генератор шақырылғанда, генератордың коды yield әрекетінен кейін жалғастырылады, басқа yield әрекетіне кездеспейінше. Yield әрекетінен басқа, генератордың коды finish әрекетімен де тоқтатылуы мүмкін, онда генераторды шақыруды қоршаған ішкі цикл аяқталады. Күрделірек жағдайларда генератор итератор жасау үшін циклдің сыртында қолмен пайдаланылуы мүмкін, одан кейін оны әртүрлі тәсілдермен қолдануға болады. Генераторлар өнімдерін тек қажет болғанда ғана есептейтіндіктен, олар бірден есептеу қиын немесе мүмкін емес тізбектер сияқты ағындарды көрсету үшін пайдалы. Мұндайларға, мысалы, шексіз тізбектер және деректердің тікелей ағындары жатады. Егер дереу бағалау қажет болса (әсіресе тізбек шекті болғанда, әйтпесе бағалау ешқашан аяқталмайды), оны тізімге түрлендіруге немесе генератордың орнына тізім құратын параллель құрылымды пайдалануға болады. Мысалы, Python-да генератор g-ді l = list(g) арқылы тізімге түрлендіруге болады, ал F#-да seq { } тізбек өрнегі жалқау түрде (генератор немесе тізбек) бағаланады, бірақ [ ] дереу (тізім) бағаланады. Генераторлардың болуы тілдің циклдық құрылымдарын, мысалы for және while, бір циклдік құрылымға дейін азайтуға мүмкіндік береді; барлық әдеттегі циклдық құрылымдарды дұрыс генераторларды тиісті түрде қолдану арқылы ыңғайлы түрде модельдеуге болады. Мысалы, x = 1 - 10 аралығындағы циклді генератор арқылы итерация ретінде жүзеге асыруға болады, мысалы, Python-да for x in range(1, 10). Сонымен қатар, break генераторға finish жіберу арқылы және содан кейін циклде continue қолдану арқылы жүзеге асырылуы мүмкін.

Уақыт шкаласы

Генераторлар алғаш рет CLU (1975 ж.) тілінде пайда болды, Icon (1977) жолдарды өңдеу тілінде маңызды рөл атқарды және қазір Python (2001), C#, Ruby, PHP, ECMAScript (ES6/ES2015 нұсқасынан бастап) және басқа да тілдерде қолжетімді. CLU және C# тілдерінде генераторлар итераторлар деп, ал Ruby тілінде – санаушылар деп аталады.

Лиспа

Common Lisp стандартының соңғы нұсқасында генераторлар болмайды, алайда CLtL2 немесе pygen-де құжатталған SERIES сияқты әртүрлі кітапханалық жүзеге асырулар бар.

С

C тілінде генератор функциялары тілдік құрылым ретінде жоқ, бірақ олар корутиналардың кіші жиыны болғандықтан, libdill сияқты стекпен жұмыс жасайтын корутиналарды іске асыратын кез келген фреймворк арқылы оларды іске асыру оңай. POSIX платформаларында, әр итерация бойынша контекст ауыстыру құны маңызды болмағанда немесе тек бір мезгілдестік емес, толық параллелизм қажет болғанда, pthreads және құбырларды пайдаланып өте қарапайым генератор функциясы фреймворкін құруға болады.

Python-тың атауы

2001 жылы 2.2 нұсқасында Python-ға генераторлар қосылды.