먼저 공식 PHP 문서에 어떻게 소개되어 있는지 살펴보겠습니다. 생성기는 간단한 객체 반복을 구현하는 더 쉬운 방법을 제공합니다. Iterator 인터페이스를 구현하기 위해 클래스를 정의하는 것에 비해 성능 오버헤드와 복잡성이 크게 줄어듭니다.
이 문장을 읽고 나면 객체 반복, 반복자 인터페이스, 성능 오버헤드, 상대적으로 추상적, 이야기가 저렴하다는 등 몇 가지 키워드를 얻을 수 있습니다. 코드를 보여주세요. 생성기의 가장 고전적인 예부터 시작하겠습니다.
PHP의 range() 함수는 메모리에 지정된 범위 단위를 포함하는 배열을 생성하고 사용 시 이를 반환합니다. 일반적으로 이것에는 문제가 없지만 전달된 제한 매개변수가 매우 클 경우에는 메모리에 생성될 배열도 매우 클 것이라는 점은 메모리의 리듬이 너무 무섭습니다. 이 시점에서 생성기를 사용하여 보다 효율적인 범위 함수를 구현할 수 있습니다(다음 코드는 공식 PHP 문서의 단순화된 버전입니다).
function xrange($start, $limit, $step = 1) { //校验参数,此处省略 for ($i = $start; $i <= $limit; $i += $step) { //向外产出值 yield $i; } } //xrange此时返回的是一个生成器对象 $gen = xrange(1, 9); //对生成器进行迭代 foreach ($gen as $number) { echo "$number "; }
xrange 및 range 함수는 여기에서 동일한 효과를 가지며 둘 다 Iterable 변수를 생성합니다. 그러나 차이점은 range 함수가 ORM에서 자주 언급되는 "사전 로드"와 약간 비슷하다는 점입니다. 반면 xrange는 "지연 로드"이고 반복이 해당 지점에 도달하여 해당 값을 생성할 때까지 기다리므로 xrange는 그럴 필요가 없습니다. 큰 메모리 블록 할당 변수를 저장하려면 메모리가 크게 절약되고 효율성이 향상됩니다.
이제 제너레이터와 일반 함수의 유사점과 차이점을 요약해 보겠습니다.
제너레이터에는 항복 키워드(결과를 생성하는 데 사용됨)가 포함되어야 하며 일반 함수에서는 결과만 외부로 반환될 수 있으므로 여러 번 나타날 수 있습니다. Return을 사용할 수 있으며 함수가 실행됩니다.
제너레이터는 return을 통해 값을 반환할 수 없습니다. 그렇게 하면 컴파일 오류가 발생합니다. PHP Fatal error: Generator는 "return"을 사용하여 값을 반환할 수 없습니다. PHP7에서는 사용할 수 없습니다. 오류가 발생하지만 실행을 계속하기 위해 생성기가 종료됩니다. 즉, valid() 메서드를 호출하면 false가 반환됩니다. 그러나 PHP5에서는 return null이 유효한 구문이므로 생성기가 종료됩니다. 그리고 계속 실행)
Generator 객체는 Generator에서 반환됩니다. 위 코드에서 $gen은 Generator 객체입니다. 제너레이터 객체는 다른 클래스의 객체와 다르다는 점에 유의하세요. new 키워드를 통해서는 생성할 수 없으며 제너레이터 함수를 통해서만 얻을 수 있습니다. 먼저 Generator 클래스 요약을 살펴보고 구성을 살펴보겠습니다.
Generator implements Iterator { /** * 返回当前产生的值(yield后面表达式的值) */ public mixed current ( void ) /** * yield的键(yield 'key'=>'val';) */ public mixed key ( void ) /** * 从上一个yield之后继续执行,直到下一个yield */ public void next ( void ) /** * 重置迭代器(对于生成器并没什么卵用) */ public void rewind ( void ) /** * 向生成器中传入一个值,并从上一个yield之后继续执行 */ public mixed send ( mixed $value ) /** * 向生成器中抛出一个异常,并从上一个yield之后继续执行 */ public void throw ( Exception $exception ) /** * 检查迭代器是否被关闭(false表示已关闭) */ public bool valid ( void ) /** * 序列化回调,但是生成器不能被序列化,因此会抛出一个异常 */ public void __wakeup ( void ) }
위 클래스 요약을 보면 Generator 클래스가 Iterator 인터페이스를 구현하므로 반복자의 특성을 가지고 있음을 알 수 있습니다. 또한, send(), throw() 및 __wekeup() 메서드를 추가합니다. 관련 메서드 설명이 주석 처리되어 여기서는 반복되지 않습니다.
글을 많이 썼는데 글이 잘 안 맞는 것 같아서 그림을 그려서 감을 잡아 보는 게 좋을 것 같아요. (그림도 별로 예쁘지 않으니 그냥 적당히 하자, 2333)
다음을 살펴보겠습니다. Yield 키워드는 가장 간단한 형태로 일반 함수의 반환과 유사합니다. 차이점은 일반 반환은 값을 반환하고 함수 실행을 종료하는 반면, Yield는 반환합니다. 이 생성기를 호출하기 위해 반복하는 코드에 값을 지정하고 생성기 함수의 실행을 일시 중지합니다.
이것은 일반적인 수익률 표현식입니다: $data = Yield $key => $value;. 이 표현식은 두 부분으로 구성됩니다:
참고: PHP5에는 괄호 $data = (yiel<br/>d $key => $value);가 필요합니다. 그렇지 않으면 컴파일 오류가 발생합니다. PHP7은 이에 대해 신경 쓸 필요가 없습니다
첫째, 단일 값 또는 키-값 쌍일 수 있는 Yield 이후의 표현식이며 배열의 요소입니다. 이에 상응하여 이 표현식의 일부는 상위 계층 호출로 반환됩니다. 즉, 상위 계층은 현재 메서드를 통해 값을 수신하거나 send 메서드의 반환 값을 실행할 수 있습니다.
다른 부분은 Yield 키워드 자체입니다. 개인적으로 수신자는 send 메소드에 의해 전달된 값을 수신하게 된다고 이해합니다. 이 값은 전체 항복 표현식의 현재 값이며 왼쪽의 변수에 의해 수신될 수 있습니다.
약간 추상적일 수 있지만 위 그림을 살펴보겠습니다.
PHP7에는 다른 생성기, Traversable 객체에서 구문을 시작할 수 있는 Yield from 키워드가 추가되었습니다. , 또는 배열 생성기 함수의 생성을 사용하여 값을 생성합니다. Yield from의 다양한 특징은 데이터를 생성하는 Yield와 동일하지만, 뒤따르는 표현이 다릅니다. 예를 살펴보겠습니다(PHP 공식 문서에서 발췌):
function count_to_ten() { yield 1; yield 2; yield from [3, 4]; //生成数组 yield from new ArrayIterator([5, 6]); //生成可遍历对象 yield from seven_eight(); //生成生成器对象 yield 9; yield 10; } function seven_eight() { yield 7; yield from eight(); } function eight() { yield 8; } foreach (count_to_ten() as $num) { echo "$num "; } //输出:1 2 3 4 5 6 7 8 9 10
yield from以方便我们编写比较清晰生成器嵌套,这点可以类比于函数中的嵌套调用,当函数A中调用另一个函数B,此时会等B执行完成并返回,方才继续执行。在没有yield from的时候,实现生成器嵌套需要自己实现栈并进行压栈和弹出操作以达到相同效果,那是多么痛苦的操作。
相关推荐:
위 내용은 PHP 생성기에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!