Language Reference >> predefined interfaces and Classes >> generator >> Send

Source: Internet
Author: User
Tags generator mixed rewind in python

Because the Send method is the key to the implementation of the coprocessor, it is necessary to learn the next send method in detail, because it is really weird; official documentation generator::send (PHP 5 >= 5.5.0, PHP 7) Generator::send-send a value to the generator Description public mixed generator::send (mixed $value )

Sends the given value to the generator as the ' result of the ' current yield expression and resumes execution of the Generato R.
Here official definition: Send method, sending a value as the result value of the yield expression that is currently being executed by the generator (the Send method does not execute the current yield expression but merely sends the value as the result of the current yield expression) ; and continue executing the generator (continue with the next yield);
A special note here is that the value sent by send is the result value of the yield expression currently being executed, and the value of send returns the result of the next yield expression;

If the generator is not in a yield expression when this is called, it would the it would be the I-let-advance to the LD expression before sending the value. As such it is isn't necessary to "prime" PHP generators with a generator::next () called (like it's done in Python).
If the current generator is not in the yield expression, it automatically runs to the first yield expression and then performs the action to send $value; therefore, it is not necessary to use Generator::next () to invoke the PHP builder (as is done in Python).
The special note here is that the first call to the Send method will cause the generator to automatically run to the position of the first yield expression and execute the first yield, followed by the call to the Send method, which is illustrated below; Parameters value

Value to send into the generator. This value would be the "return value" of the yield expression the generator is currently at. return Values

Returns the yielded value.
This indicates that the value returned is the value of the executed yield expression, but it is possible to span two yield expressions once the Send method is run, so the definition here is ambiguous; EXP1

function Task () {
    echo "This is segment 1\n";//Here is the first program segment, before the first yield;
    $a = yield ' step 1 ';
    echo "Get Step 1 Send value: $a \ n";
    echo "This is segment 2\n"; This is the second program segment, after the first yield, before the second yield;
    $b = Yield ' Step 2 ';
    echo "Get step 2 send value: $b \ n";
    echo "This is segment 3\n"; This is the third program segment, after the second yield;
}
$task = Task ();
$sendResult = $task->send (' The ' a ');
echo "the": $sendResult \ n ";
/**
 * Output:
 * This are segment 1
 * Get step 1 Send value:first send
 * This is segment 2
 * The Firs T send result:step 2
 * *

According to the above example:
The value sent by the Send method, first send, is the result value of the yield (step 1);
The return value of the Send method is the value of the second yield (step 2) expression;

There are questions:
See Brother Bird's article that, when a generator method is invoked, the rewind method will automatically execute, and PHP's official website Face Remind Method description is simple Generator::rewind-rewind the iterator, So when the rewind method is invoked, the generator will not automatically execute to the position of the first yield expression. Let's look at the next example, assigning a generator function to a variable alone; EXP2

function Task () {
    echo "This is segment 1\n";//Here is the first program segment, before the first yield;
    $a = yield ' step 1 ';
    echo "Get Step 1 Send value: $a \ n";
    echo "This is segment 2\n"; This is the second program segment, after the first yield, before the second yield;
    $b = Yield ' Step 2 ';
    echo "Get step 2 send value: $b \ n";
    echo "This is segment 3\n"; This is the third program segment, after the second yield;
}
$task = Task ();
/**
 * Output: * *
 

The output is empty, and you can tell that when the generator function is assigned a value, the code inside the generator is not executed; that is to say, in the EXP1 example, the execution of the code is caused by the Send method; EXP3

In the definition of the Send method:

The Send method, which sends the result value of a yield expression that makes a value as the generator is currently executing, and continues to execute the builder, which should be more accurately described: Continue with the next yield;

function task () {echo "This is segment 1\n";//Here is the first program segment, before the first yield; $a = yield ' Step 1 '
    ;
    echo "Get Step 1 Send value: $a \ n"; echo "This is segment 2\n";
    This is the second program segment, after the first yield, before the second yield; $b = Yield ' Step 2 ';
    echo "Get step 2 send value: $b \ n"; echo "This is segment 3\n";
This is the third program segment, after the second yield;} $task = task ();
$sendResult = $task->send (' The ' a ');
echo "the": $sendResult \ n ";
$sendResult = $task->send (' second send ');
echo "The second send result: $sendResult \ n";  /** * Output: * This is segment 1 * Get step 1 Send value:first Send * the ' is segment 2 * the ' 2 * Get step 2 Send value:second Send * * Segment 3 * The second send result: */

In this example, the return value of the first send method is the result of the second yield expression, and the value sent by the second send method becomes the result value of the second yield expression; Two send methods have operations on the second yield expression during execution So who actually executed the second yield expression? According to the official website, the first send method executes the second yield expression, because the result value of the first send method is the result value of the second yield expression, then the second send method is simply the result of the second yield expression that will send the argument , and the second yield expression is not executed; if so, then the first yield expression is not executed, because if the second send method does not execute the second yield expression, then the first send method does not execute the first yield expression. So the first yield expression is really not executed. EXP4

function task () {echo "This is segment 1\n";//Here is the first program segment, before the first yield; $a = yield son_tas
    K (1);
    echo "Get Step 1 Send value: $a \ n"; echo "This is segment 2\n";
    Here is the second procedure, after the first yield, before the second yield; $b = yield son_task (2);
    echo "Get step 2 send value: $b \ n"; echo "This is segment 3\n";
    Here is the third procedure segment, after the second yield, before the third yield; $c = yield son_task (3);
    echo "Get step 3 Send value: $c \ n"; echo "This is segment 4\n";
    Here is the fourth program segment, after the third yield;} function Son_task ($step) {echo "This is son_task the step $step \ n";
Return to "Step $step";
} $task = Task ();
$sendResult = $task->send (' The ' a ');
echo "the": $sendResult \ n ";
 /** * Output: * This is segment 1 * It is son_task of the step 1 * Get step 1 Send value:first Send * the IS segment 2 * This is son_task the ' Step 2 * the ' the ' result:step 2 */

The

is known from the example above: the first Send method executes the first yield expression and the second yield expression; EXP5

function Task () {echo "This is segment 1\n";//Here is the first program segment, before the first yield; $a = yield son_task (1);
    echo "Get Step 1 Send value: $a \ n"; echo "This is segment 2\n";
    Here is the second procedure, after the first yield, before the second yield; $b = yield son_task (2);
    echo "Get step 2 send value: $b \ n"; echo "This is segment 3\n";
    Here is the third procedure segment, after the second yield, before the third yield; $c = yield son_task (3);
    echo "Get step 3 Send value: $c \ n"; echo "This is segment 4\n";
    Here is the fourth program segment, after the third yield;} function Son_task ($step) {echo "This is son_task the step $step \ n";
Return to "Step $step";
} $task = Task ();
$sendResult = $task->send (' The ' a ');
echo "the": $sendResult \ n ";
$sendResult = $task->send (' second send ');
echo "The second send result: $sendResult \ n";
 /** * Output: * This is segment 1 * It is son_task of the step 1 * Get step 1 Send value:first Send * the IS segment 2 * This is son_task of step 2 * the "the" Result:step 2 * Get step 2 send Value:second SEnd * This is segment 3 * It is son_task of step 3 * The second send result:step 3 * * 

By comparing EXP4 and EXP5, the second send method simply runs the third yield expression and does not run the second yield expression;
Here also can be learned that when the first operation of the Send method, the official website inside the special instructions:

If the current generator is not in the yield expression, it automatically runs to the first yield expression and then performs the action to send $value; therefore, it is not necessary to use Generator::next () to invoke the PHP builder (as is done in Python).

The more accurate implication is that if the current builder's position is not in the yield expression, the Send method of the call builder will cause the generator to automatically run the code to the first yield expression and execute the first yield expression While the value sent by this send method will be the result of the first yield expression currently in place, the Send method will let the generator continue with the next yield expression and the result value of the next yield expression as the return value of the Send method;
In other words, the official website inside the current yield expression position, is currently implemented yield expression;
If you are currently in a yield expression position, then using the Send method replaces only the result value of the yield expression at the current position, executes the next yield expression and takes the result value as the return value of the Send method; EXP6

We now look back at all the examples above, where the result of the first expression is not returned; that is, we cannot get the value of the first yield expression in the generator by using the Send method, because the Send method replaces only the result value of the first yield expression inside the generator. This value is not obtained, so we need to use the current method to get the value of the first yield expression at the first time the generator executes;

function Task ()
{
    echo "This is segment 1\n";//Here is the first program segment, before the first yield;
    $a = yield son_task (1);
    echo "Get Step 1 Send value: $a \ n";
    echo "This is segment 2\n"; Here is the second procedure, after the first yield, before the second yield;
    $b = Yield son_task (2);
    echo "Get step 2 send value: $b \ n";
    echo "This is segment 3\n"; Here is the third procedure segment, after the second yield, before the third yield;
    $c = Yield son_task (3);
    echo "Get step 3 Send value: $c \ n";
    echo "This is segment 4\n"; Here is the fourth program segment, after the third yield;

}

function Son_task ($step)
{
    echo "This is son_task the step $step \ n";
    Return "Step $step";
}

$task = Task ();
$current = $task->current ();
echo "This is yield value: $current \ n";
/**
 * Output: * This is segment 1 * It is son_task the step 1 * This A-
 yield value:step 1
 * *

Also, we have questions about whether the current method executes the present yield, so: EXP7

function Task () {echo "This is segment 1\n";//Here is the first program segment, before the first yield; $a = yield son_task (1);
    echo "Get Step 1 Send value: $a \ n"; echo "This is segment 2\n";
    Here is the second procedure, after the first yield, before the second yield; $b = yield son_task (2);
    echo "Get step 2 send value: $b \ n"; echo "This is segment 3\n";
    Here is the third procedure segment, after the second yield, before the third yield; $c = yield son_task (3);
    echo "Get step 3 Send value: $c \ n"; echo "This is segment 4\n";
    Here is the fourth program segment, after the third yield;} function Son_task ($step) {echo "This is son_task the step $step \ n";
Return to "Step $step";
} $task = Task ();
$sendResult = $task->send (' The ' a ');
echo "the": $sendResult \ n ";
$current = $task->current ();
echo "This current value: $current \ n";
 /** * Output: * This is segment 1 * It is son_task of the step 1 * Get step 1 Send value:first Send * the IS segment 2 * This is son_task of step 2 * the ' result:step ' 2 * This value:step 2 * *

Comparing EXP6 and EXP7, it is found that current is automatically executed to the first yield position when the generator is not in yield, and executes it, and this time I think of what brother Bird said. The rewind operation has been implicitly performed while generating an iterative object , but the experiment found that when generating the generator did not execute the generator inside the operation, but when using the Current,send method (guess next method can also) automatically execute the generator inside the code to the first yield position;
So since there are so many exp, it is not bad for this one; EXP8

function Task ()
{
    echo "This is segment 1\n";//Here is the first program segment, before the first yield;
    $a = yield son_task (1);
    echo "Get Step 1 Send value: $a \ n";
    echo "This is segment 2\n"; Here is the second procedure, after the first yield, before the second yield;
    $b = Yield son_task (2);
    echo "Get step 2 send value: $b \ n";
    echo "This is segment 3\n"; Here is the third procedure segment, after the second yield, before the third yield;
    $c = Yield son_task (3);
    echo "Get step 3 Send value: $c \ n";
    echo "This is segment 4\n"; Here is the fourth program segment, after the third yield;

}

function Son_task ($step)
{
    echo "This is son_task the step $step \ n";
    Return "Step $step";
}

$task = Task ();
$task->rewind ();
/**
 * Output:
 * This is segment 1 * It is son_task the step
 1
 * *

It is now known that the Rewind method is to execute the generator to the first yield expression position and to perform the first yield expression;
comparing EXP8 and EXP2, it is known that the rewind operation was not performed when the generator was built Instead, the rewind method is automatically executed once when a method such as Send is invoked;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.