PHP-дегі кірістілік дегеніміз не?

Мен жақында осы кодқа нұқсан келтірдім:

 function xrange($min, $max) { for ($i = $min; $i <= $max; $i++) { yield $i; } } 

Мен бұл кілт сөздің yield ешқашан көрген емеспін. Кодты іске қосуға тырысамын, мен аламын

Талдау қатесі: синтаксистік қате, x жолындағы күтпеген T_VARIABLE

Сонымен, yield кілт сөзі дегеніміз не? PHP шынымен бе? Егер солай болса, оны қалай пайдалануға болады?

143
05 июля '13 в 10:53 2013-07-05 10:53 Гордон 05.07.2013 жылы 10:53 орнатылды 2013-07-05 10:53
@ 5 жауаптар

Өнімділік дегеніміз не?

Берілген кілт сөз генератор функциясының деректерін қайтарады:

Генератор функциясының жүрегі - кірістілік кілт сөзі. Кәдімгі түрде, кірістілік туралы мәлімдеме қайтару мәлімдемесі сияқты көрінеді, бірақ функцияны тоқтатудың орнына, кірістілік орнына циклдің циклінің мәнін генераторға береді және генератордың функциясын тоқтатады.

Генератордың функциясы қандай?

Генератордың функциясы - бұл итераторды жазудың ықшам әрі тиімді тәсілі. Бұл функцияны (сіздің xrange ) анықтауға мүмкіндік береді, ол сіз оны қайта есептеу кезінде мәндерді есептеп, қайтарады:

 foreach (xrange(1, 10) as $key => $value) { echo "$key => $value", PHP_EOL; } 

Бұл келесі шығарылымды жасайды:

 0 => 1 1 => 2 … 9 => 10 

Сіз сондай-ақ $key пайдаланып foreach те басқара аласыз

 yield $someKey => $someValue; 

Генератордың функциясында $someKey деген $key және $someValue мәнін білдіреді, яғни $val мәні. Үлгі мәселеде $i .

Қалыпты функциялармен қандай айырмашылық бар?

Енді сіз осы нәтижеге жету үшін неге PHP-дің өздік range функциясын ғана пайдаланбайтынымызды сұрайтын шығарсыз. Және сіз дұрыс. Нәтиже бірдей болады. Бұл жерде айырмашылық бар.

PHP range қолданған кезде біз оны орындаймыз, жадыдағы барлық сандар жиынын foreach return бүтін алапты foreach return , ол содан кейін оған шығып, мәндерді шығарады. Басқаша айтқанда, foreach массивтің өзінде жұмыс жасайды. range және foreach функциясы тек бір рет «сөйлесу» функциясы. Поштадағы буманы қалай алу туралы ойланыңыз. Жеткізуші жігіт сіздерге орама береді және кетеді. Содан кейін барлық пакетті ашып, барлығын алып тастайсыз.

Генератор функциясын пайдаланған кезде, PHP функцияға кіреді және оны соңына немесе yield кілт сөзіне сай болғанша орындайды. Ол yield кездескенде, ол сол кездегі мәнді сыртқы циклге қайтарады. Содан кейін генераторлық функцияға оралады және ол қабылданатын жерінен жалғасады. Сіздің xrange for цикл бар, ол $max жеткенше жұмыс істейді және жұмыс істейді. Бұны foreach және ping pong генераторы ретінде ойлап көріңіз.

Неге маған керек?

Генераторларды жад көлемін шектеу үшін қолдануға болады. Сіздің ортаңызға байланысты, range(1, 1000000) сіздің сценарийіңіздің қайтыс болуына алып келеді, ал генератормен бірге жұмыс істейді. Немесе, Википедия жазғандай:

Себебі генераторлар сұраныс бойынша алынған мәндерді есептейді, олар қымбат немесе бірден есептеу мүмкін емес тізбектерді ұсыну үшін пайдалы. Олар, мысалы, тірі деректердің шексіз тізбектері мен ағындарын қамтиды.

Генераторлар да жылдам болуы керек. Бірақ тез сөйлеген кезде біз әдетте өте аз мөлшерде сөйлейтінімізді есте сақтаңыз. Сондықтан сіз генераторларды пайдалану үшін барлық кодтан қашып, оны өзгертпес бұрын, мағынасы қай жерде екенін анықтау үшін тексеру жасаңыз.

Генераторларға арналған басқа да пайдалану жағдайында асинхронды сопроводы болып табылады. Кілт сөзі құндылықтарды қайтарумен қатар, оларды қабылдайды. Бұл туралы қосымша ақпарат алу үшін төмендегі екі тамаша блог жазбасын қараңыз.

Қай уақыттан бастап yield пайдалануға болады?

Генераторлар PHP 5.5- ке енгізілді. Осы нұсқаға yield пайдалану тырысып, кілт сөздің соңында кодқа байланысты әртүрлі талдаулар қателерін тудырады. Сондықтан осы кодтан талдау қатесін алсаңыз, PHP-ді жаңартыңыз.

Көздер және одан әрі оқу:

208
05 июля '13 в 10:53 2013-07-05 10:53 Гордон жауап 05.07.13 10:53 2013-07-05 10:53

yield кілт сөзі PHP 5.5-де «генераторларды» анықтау үшін қолданылады. Сонымен генератор дегеніміз не?

Php.net торабынан:

Генераторлар қарапайым итераторларды Iterator интерфейсін іске асыратын сыныпты іске асырудың артық немесе қиындықсыз іске асырудың жеңіл әдісін ұсынады.

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

border=0

Осы жерден: генераторлар = генераторлар, басқа функциялар (қарапайым функциялар) = функциялар.

Осылайша, олар пайдалы:

  • қарапайым заттарды (қарапайым заттарды) жасау керек;

    Генератор жиынтығы

    Итератор интерфейсін іске асыруға қарағанда әлдеқайда қарапайым. Екінші жағынан, генераторлар аз функционалды болып табылатын көз. оларды салыстыру .

  • Сіз деректерді сақтаудың үлкен көлемін жасауыңыз керек;

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

  • аралық мәндерге байланысты тізбекті қалыптастыру қажет

    Бұл алдыңғы ойдың жалғасы. генераторлар функциямен салыстырғанда операцияны жеңілдете алады. Фибоначчи мысалын тексеріп, генераторсыз тізбекті жасауға тырысыңыз. Сондай-ақ, генераторлар тез жұмыс істей алады - бұл, кем дегенде, жергілікті айнымалыларда аралық мәндерді сақтауға байланысты;

  • өнімділікті жақсарту қажет.

    олар кей жағдайларда кейбір функцияларда жылдамырақ жұмыс істей алады (алдыңғы артықшылығын қараңыз);

17
05 июля '13 в 15:10 2013-07-05 15:10 жауап QArea 5 шілде, 13 сағат 15:10 берілді 2013-07-05 15:10

қарапайым мысал

 <?php echo '#start main# '; function a(){ echo '{start['; for($i=1; $i<=9; $i++) yield $i; echo ']end} '; } foreach(a() as $v) echo $v.','; echo '#end main#'; ?> 

Шығу

 #start main# {start[1,2,3,4,5,6,7,8,9,]end} #end main# 
9
28 сент. Жауап 28 қар. 2016-09-28 15:29 '16 at 15:29 2016-09-28 15:29

yield сіз бір функциядағы бірнеше тапсырмалар арасындағы тоқтау нүктелерін оңай сипаттай аласыз. Бұл бәрі, бұл туралы ерекше ештеңе жоқ.

 $closure = function ($injected1, $injected2, ...){ $returned = array(); //task1 on $injected1 $returned[] = $returned1; //I need a breakpoint here!!!!!!!!!!!!!!!!!!!!!!!!! //task2 on $injected2 $returned[] = $returned2; //... return $returned; }; $returned = $closure($injected1, $injected2, ...); 

Егер тапсырма1 және тапсырма2 бір-бірімен байланысты болса, бірақ басқа нәрсе жасау үшін тоқтау нүктесі қажет:

  • деректер базасының өңдеуі арасындағы бос жады
  • келесі тапсырмаға тәуелділікті қамтамасыз ететін басқа да тапсырмаларды орындаңыз, бірақ ағымдағы кодты түсінуге байланысты емес
  • асинхронды қоңыраулар жасау және нәтижелерді күту
  • және т.б.

содан кейін генераторлар - ең жақсы шешім, себебі сіздің кодты бірнеше тұйықтауға бөлуге немесе оны басқа кодпен араластыруға немесе кері қоңырауларды пайдалануға болмайды. Сіз тоқтау нүктесін қосу үшін yield пайдаланасыз және сіз дайын болсаңыз, сол тоқтау нүктесінен жалғастыруға болады.

Генераторсыз тоқтау нүктесін қосыңыз:

 $closure1 = function ($injected1){ //task1 on $injected1 return $returned1; }; $closure2 = function ($injected2){ //task2 on $injected2 return $returned1; }; //... $returned1 = $closure1($injected1); //breakpoint between task1 and task2 $returned2 = $closure2($injected2); //... 

Генераторлармен тоқтау нүктесін қосыңыз

 $closure = function (){ $injected1 = yield; //task1 on $injected1 $injected2 = (yield($returned1)); //task2 on $injected2 $injected3 = (yield($returned2)); //... yield($returnedN); }; $generator = $closure(); $returned1 = $generator->send($injected1); //breakpoint between task1 and task2 $returned2 = $generator->send($injected2); //... $returnedN = $generator->send($injectedN); 

Ескерту Генераторлармен қателесу оңай, сондықтан оларды енгізбес бұрын әрқашан бірлік сынақтарын жазыңыз! note2: Генераторларды шексіз циклде пайдалану шексіз ұзындығы бар циклды жазу сияқты.

6
15 апр. жауап берді inf3rno 15 сәу 2014-04-15 04:52 '14 at 4:52 2014-04-15 04:52

Бұл функция шығуды қолданады:

 function a($items) { foreach ($items as $item) { yield $item + 1; } } 

бұл шамамен бірдей:

 function b($items) { $result = []; foreach ($items as $item) { $result[] = $item + 1; } return $result; } 

Жалғыз айырмашылық мынада, a() генераторды қайтарады және b() қарапайым массив. Дегенмен, сіз екеуінде де қайталауға болады, бұл маңызды аспект.

1
24 апр. жауап tsusanka 24 apr беріледі. 2017-04-24 22:18 '17 сағат 10 : 18-де 2017-04-24 22:18