The yield is PHP What the hell

Source: https://segmentfault.com/a/1190000018457194

 

In fact, I am not because iteration or generator or research PHP manual only know of yield, but for coroutines, I still do not know PHP there are yield such a hell. People from PHP 5.5 this thing is to start the introduction of the official name is called generator. Why do you say 5.5 years of things, and now it is brought out. I also want to ask you yo, PHP 5.3 will have a namespace for the hair to the last few years was officially put into operation.

So, the question is, is this thing in the end what is the use?

First to experience a problem, you 100Kb of memory (yes, you read right, is 100Kb), then let you output a iterations starting from 1 up to 10,000 array, step 1.

The more first iteration of the array, you must first create an array.

Therefore, a forehead beat code cook follows:

<?php
$start_mem = memory_get_usage();
$arr = range( 1, 10000 );
foreach( $arr as $item ){
  //echo $item.',';
}
$end_mem = memory_get_usage();
echo " use mem : ". ( $end_mem - $start_mem ) .'bytes'.PHP_EOL;

Operating meal fierce as a tiger, run the score 1-5, you feel:

528440bytes, it is approximately 528Kb, 100Kb is almost five times, and the mother of this day could not have.

 

After all, you know, recent memory prices really expensive, countries are called low-carbon energy saving, you spend more than 5 times the memory, it means that carbon dioxide emissions more than 5 times, it means more money to contribute to the memory of the multi-purpose to stick ... ... you think about it, that's the stick.

People are forced out, so the yield can save games, and probably the code below, note the following:

 

<?php
$start_mem = memory_get_usage();
function yield_range( $start, $end ){
  while( $start <= $end ){
    $start++;
    yield $start;
  }
}
foreach( yield_range( 0, 9999 ) as $item ){
  echo $item.',';
}
$end_mem = memory_get_usage();
echo " use mem : ". ( $end_mem - $start_mem ) .'bytes'.PHP_EOL;

Run, do you feel:

First, we look at yield_range this function with the normal function is not the same place, that is a normal function to return the results are often use return, and this is the yield. Followed by an ordinary function can return only once in return, the yield can return many times.

So, we have to analyze this amazing wave of children yield_range function. The yield keyword in the end what is the return? We simply look at:

<?php
function yield_range( $start, $end ){
  while( $start <= $end ){
    $start++;
    yield $start;
  }
}
$rs = yield_range( 1, 100 );
var_dump( $rs );
/*
object(Generator)#1 (0) {
}
*/

yield return is the object of an object called Generator (Chinese name is the generator), and this generation is realized Iterator interface (as for the Iterator interface, you go to the PHP manual on the search bar). So, since realized Iterator interface (? Precisely because of this, this thing can use foreach to iterate, understand it), so you can have the following code:

<?php
function yield_range( $start, $end ){
  while( $start <= $end ){
    yield $start;
    $start++;
  }
}
Generator $ = yield_range (. 1, 10 );
 // Valid () method of current () next () Iterator interface is 
the while ( $ Generator -> Valid ()) {
   echo  $ Generator -> Current (). value is PHP_EOL ;
   Generator $ -> the Next ();
}

Run results are shown below:

 

Focus here: the yield_range function seems to be able to remember the last time it runs to where, what is the result of the last run, and then followed by the time the next time you run continued resumes from where it last ended. This is not a PHP function can do it!

We know that the operating system at the time of the scheduling process, will trigger a concept called "process context switch" is. A dispatch from the process such as CPU to process B, then again when the process from A to B process scheduling, where process A had to run, and temporary data are the result of what needs to be restored, otherwise, everything from scratch, it would be a big problem. And, the yield keyword appears in user mode (non-system kernel level) can realize this concept. So, do iteration with yield, fear is one thing that really unpromising, it can do too much.

Then, we need to know a method a generator object, called send, simply look at this lump of code below:

<?php
function yield_range( $start, $end ){
  while( $start <= $end ){
    $ret = yield $start;
    $start++;
    echo "yield receive : ".$ret.PHP_EOL;
  }
}
$generator = yield_range( 1, 10 );
$generator->send( $generator->current() * 10 );

The results shown in FIG Run:

send ways to modify yield of return value, but you can not take it for granted, such as the following this lump of code, do you think the result is what it running?

<?php
function yield_range( $start, $end ){
  while( $start <= $end ){
    $ret = yield $start;
    $start++;
    echo "yield receive : ".$ret.PHP_EOL;
  }
}
$generator = yield_range( 1, 10 );
foreach( $generator as $item ){
  $generator->send( $generator->current() * 10 );
}

Originally thought operating results are similar to this:

<?php
yield receive : 10
yield receive : 20
yield receive : 30
yield receive : 40
yield receive : 50
yield receive : 60
yield receive : 70
yield receive : 80
yield receive : 90
yield receive : 100

However, materialist tell us:

The result is her face, and you feel:

what is the reason? The reason is that when you send send to the yield on the outside, will automatically trigger a next, try it yourself.

Guess you like

Origin www.cnblogs.com/laijinquan/p/11871309.html