추천: "PHP 비디오 튜토리얼"
PHP 5.5부터 PHP는 Generator
라는 새로운 기능을 추가했습니다. 이는 중국어로 로 번역됩니다. 생성기. 생성기는 객체 반복을 구현하는 데 간단하게 사용할 수 있습니다. 간단한 공식 예제부터 시작해 보겠습니다. <code>Generator
,中文译为生成器
。生成器可以简单地用来实现对象的迭代,让我们先从官方的一个小例子说起。
在 PHP 中,我们都知道,有一个函数叫做 range
,用来生成一个等差数列的数组,然后我们可以用这个数组进行 foreach
的迭代。具体就想这样。
foreach (range(1, 100, 2) as $num) { echo $num . PHP_EOL; }
这一段代码就会输出首项为 1,末项为 100,公差为 2 的等差数列。它的执行顺序是这样的。首先,range(1, 100, 2)
会生成一个数组,里面存了上面那样的一个等差数列,之后在 foreach
中对这个数组进行迭代。
那么,这样就会出现一个问题,如果我要生成 100 万个数字呢?那我们就要占用上百兆内存。虽然现在内存很便宜,但是我们也不能这么浪费内存嘛。那么这时,我们的生成器就可以排上用场了。考虑下面的代码。
function xrange($start, $limit, $step = 1) { while ($start <= $limit) { yield $start; $start += $step; } } foreach (xrange(1, 100, 2) as $num) { echo $num . PHP_EOL; }
这段代码所的出来的结果,和前面的那段代码一模一样,但是,它内部的原理是天翻地覆了。
我们刚才说了,前面的代码,range
会生成一个数组,然后 foreach
来迭代这个数组,从而取出某一个值。但是这段代码呢,我们重新定义了一个 xrange
函数,在函数中,我们用了一个关键字 yield
。我们都知道定义一个函数,希望它返回一个值得时候,用 return
来返回。那么这个 yield
呢,也可以返回一个值,但是,它和 return
是截然不同的。
使用 yield
关键字,可以让函数在运行的时候,中断,同时会保存整个函数的上下文,返回一个 Generator
类型的对象。在执行对象的 next
方法时,会重新加载中断时的上下文,继续运行,直到出现下一个 yield
为止,如果后面没有再出现 yield
,那么就认为整个生成器结束了。
这样,我们上面的函数调用可以等价地写成这样。
$nums = xrange(1, 100, 2); while ($nums->valid()) { echo $nums->current() . "\n"; $nums->next(); }
在这里,$num
是一个 Generator
的对象。我们在这里看到三个方法,valid
、current
和 next
。当我们函数执行完了,后面没有 yield
中断了,那么我们在 xrange
函数就执行完了,那么 valid
方法就会变成 false
。而 current
呢,会返回当前 yield
后面的值,这是,生成器的函数会中断。那么在调用 next
方法之后,函数会继续执行,直到下一个 yield
出现,或者函数结束。
好了,到这里,我们看到了通过 yield
来“生成”一个值并返回。其实,yield
其实也可以这么写 $ret = yield;
。同返回值一样,这里是将一个值在继续执行函数的时候,传值进函数,可以通过 Generator::send($value)
来使用。例如。
function sum() { $ret = yield; echo $ret . PHP_EOL; } $sum = sum(); $sum->send('I am from outside.');
这样,程序就会打印出 send
方法传进去的字符串了。在 yield
的两边可以同时有调用。
function xrange($start, $limit, $step = 1) { while ($start <= $limit) { $ret = yield $start; $start += $step; echo $ret . PHP_EOL; } } $nums = xrange(1, 100, 2); while ($nums->valid()) { echo $nums->current() . "\n"; $nums->send($nums->current() + 1); }
而像这样的使用,send()
可以返回下一个 yield
的返回。
对于 yield
,我们可以这样使用 yield $id => $value
,这是,我们可以通过 key
方法来获取 $id
,而 current
方法返回的是 $value
。
这个方法,可以帮我们让生成器重新开始执行并保存上下文,同时呢,会返回第一个 yield
返回的内容。在第一次执行 send
方法的时候,rewind
会被隐式调用。
这个方法,向生成器中,抛送一个异常。
yield
作为 PHP 5.5 的新特性,让我们用了新的方法来高效地迭代数据。同时,我们还可以使用 yield
range
라는 함수가 있다는 것을 모두 알고 있으며, 이 배열을 사용하여 다음 작업을 수행할 수 있습니다. foreach
의 반복입니다. 구체적으로 내가 하고 싶은 일은 이것이다. 🎜rrreee🎜이 코드 조각은 첫 번째 항이 1, 마지막 항이 100, 공차가 2인 산술 시퀀스를 출력합니다. 실행 순서는 다음과 같습니다. 먼저 range(1, 100, 2)
는 위와 같이 산술 시퀀스를 저장하는 배열을 생성한 다음 foreach
에서 이 배열을 반복합니다. 🎜🎜그러면 질문이 생깁니다. 100만 개의 숫자를 생성하려면 어떻게 해야 할까요? 그러면 우리는 수백 메가바이트의 메모리를 차지하게 될 것입니다. 지금은 메모리 가격이 매우 저렴하지만 이렇게 메모리를 낭비할 수는 없습니다. 그러면 이때 발전기가 유용할 수 있습니다. 다음 코드를 고려해보세요. 🎜rrreee🎜이 코드의 결과는 이전 코드와 완전히 동일하지만 내부 원리는 완전히 다릅니다. 🎜🎜이전 코드에서 range
가 배열을 생성한 다음 foreach
가 배열을 반복하여 특정 값을 추출한다고 말했습니다. 하지만 이 코드에서는 xrange
함수를 다시 정의했습니다. 함수에서 yield
라는 키워드를 사용했습니다. 우리 모두는 함수를 정의하고 값을 반환할 것으로 예상할 때 return
을 사용하여 값을 반환한다는 것을 알고 있습니다. 따라서 이 yield
도 값을 반환할 수 있지만 return
과는 완전히 다릅니다. 🎜🎜 yield
키워드를 사용하면 함수가 실행되는 동안 함수를 중단하고, 전체 함수의 컨텍스트를 저장하고, Generator
유형의 개체를 반환할 수 있습니다. 개체의 next
메서드가 실행되면 중단 당시의 컨텍스트가 다시 로드되고 가 없으면 다음 <code>yield
가 나타날 때까지 작업이 계속됩니다. Yield가 나타나면 전체 생성기가 완료된 것으로 간주됩니다. 🎜🎜이런 식으로 위의 함수 호출을 다음과 같이 동등하게 작성할 수 있습니다. 🎜rrreee🎜여기서 $num
은 Generator
의 객체입니다. 여기에는 valid
, current
및 next
라는 세 가지 메서드가 있습니다. 함수가 실행되고 나중에 yield
중단이 없으면 xrange
의 함수가 실행되고 valid
메서드는 거짓. current
의 경우 현재 yield
뒤에 있는 값을 반환합니다. 이는 생성기 기능이 중단된다는 의미입니다. 그런 다음 next
메서드를 호출한 후 다음 yield
가 나타나거나 함수가 종료될 때까지 함수가 계속 실행됩니다. 🎜🎜좋아, 여기서는 yield
가 값을 "생성"하고 반환하는 데 사용되는 것을 볼 수 있습니다. 실제로 yield
는 $ret = Yield;
로 쓸 수도 있습니다. 반환 값과 마찬가지로 여기서는 함수를 계속 실행할 때 값이 함수에 전달됩니다. Generator::send($value)
를 통해 사용할 수 있습니다. 예를 들어. 🎜rrreee🎜이러한 방식으로 프로그램은 send
메소드에 의해 전달된 문자열을 인쇄합니다. yield
양쪽에서 동시에 호출이 있을 수 있습니다. 🎜rrreee🎜그리고 이와 같이 사용하기 위해 send()
는 다음 yield
의 반환을 반환할 수 있습니다. 🎜🎜기타 생성기 메서드🎜yield
의 경우 yield $id => $value
를 사용할 수 있습니다. 즉, key
메소드를 통해 $id
를 얻을 수 있고 current
메소드는 $value
를 반환합니다. 🎜yield . <code>send
메소드가 처음 실행되면 rewind
가 암시적으로 호출됩니다. 🎜yield
PHP 5.5의 새로운 기능으로 데이터를 효율적으로 반복하는 새로운 방법을 사용합니다. 동시에 yield
를 사용하여 코루틴을 구현할 수도 있습니다. 🎜위 내용은 PHP의 Generator를 이해하도록 안내합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!