PHP 생성기 사용 상세 정보

7434 단어 php생성기

무엇이 생성기입니까?


고대상의 이름을 들으니 무언가를 창조하는 기능처럼 느껴지지만 실제로 생성기는 교체에 사용되는 교체기다.이것은 간단한 대상 교체를 실현하는 더욱 쉬운 방식을 제공했다. 정의 클래스가 Iterator 인터페이스를 실현하는 방식과 비교하면 성능 비용과 복잡성이 크게 낮아졌다.
한참 동안 말했으니 코드를 직접 보는 것이 더 직관적이다.

function test1()
{
    for ($i = 0; $i < 3; $i++) {
        yield $i + 1;
    }
    yield 1000;
    yield 1001;
}

foreach (test1() as $t) {
    echo $t, PHP_EOL;
}

// 1
// 2
// 3
// 1000
// 1001
이렇게 간단한 코드야.우선, 생성기는 반드시 방법에서 yield 키워드를 사용해야 한다.그 다음에 모든 yield는 리턴이라고 볼 수 있다.마지막으로, 외부 순환을 할 때, 한 번에 yield의 반환 값을 가져옵니다.이 예에서 세 번 순환하면 1, 2, 3이라는 세 개의 숫자가 되돌아온다.그리고 순환 외부에 두 줄의 yield를 써서 각각 1000과 1001을 출력했다.따라서 외부의 foreach는 모두 다섯 번 순환 출력되었다.
신기하죠, 분명히 하나의 방법인데, 왜 그것을 순환할 수 있는지, 그것도 이상한 순환체로 돌아가는 형식입니다.이 test () 방법을 직접 인쇄해서 인쇄한 것이 무엇인지 봅시다.

//  
var_dump(test1());

// Generator Object
// (
// )
yield를 사용하여 내용을 되돌린 후,Generator 대상을 되돌려줍니다.이 대상을 생성기 대상이라고 하는데, 이것은 new에 의해 직접 실례화될 수 없고, 생성기 함수를 통해서만 되돌아올 수 있다.이 클래스는current (), key () 등의 방법을 포함하고 가장 주요한 이 클래스는Iterator 인터페이스를 실현하기 때문에 이것은 특수한 교체기 클래스이다.

Generator implements Iterator {
    /*   */
    public current ( void ) : mixed
    public key ( void ) : mixed
    public next ( void ) : void
    public rewind ( void ) : void
    public send ( mixed $value ) : mixed
    public throw ( Exception $exception ) : void
    public valid ( void ) : bool
    public __wakeup ( void ) : void
}

생성기는 무슨 소용이 있습니까?


한참 동안 하면 교체기 아닌가?이렇게 귀찮게 왜 그래, 직접 교체기나 방법으로 한 개의 수조로 돌아가면 되지 않겠니?그래, 정상적인 상황에서는 정말 이렇게 번거롭지 않지만, 데이터의 양이 매우 많은 상황에서, 이 생성기는 그것의 강력한 위력을 발휘할 수 있을 것이다.생성기의 가장 강력한 부분은 이 일련의 데이터를 저장하기 위해 하나의 수조나 그 어떠한 데이터 구조도 필요하지 않다는 데 있다.매번 교체는 코드가 yield에 실행될 때 동적으로 되돌아옵니다.따라서 생성기는 메모리를 크게 절약할 수 있다.

//  
$start_time = microtime(true);
function test2($clear = false)
{
    $arr = [];
    if($clear){
        $arr = null;
        return;
    }
    for ($i = 0; $i < 1000000; $i++) {
        $arr[] = $i + 1;
    }
    return $arr;
}
$array = test2();
foreach ($array as $val) {
}
$end_time = microtime(true);

echo "time: ", bcsub($end_time, $start_time, 4), PHP_EOL;
echo "memory (byte): ", memory_get_usage(true), PHP_EOL;

// time: 0.0513
// memory (byte): 35655680

$start_time = microtime(true);
function test3()
{
    for ($i = 0; $i < 1000000; $i++) {
        yield $i + 1;
    }
}
$array = test3();
foreach ($array as $val) {

}
$end_time = microtime(true);

echo "time: ", bcsub($end_time, $start_time, 4), PHP_EOL;
echo "memory (byte): ", memory_get_usage(true), PHP_EOL;

// time: 0.0517
// memory (byte): 2097152
상술한 코드는 1000000개의 순환을 간단하게 진행한 후에 결과를 얻을 수 있을 뿐이지만 직관적으로 볼 수 있다.생성기를 사용한 버전은 2M의 메모리만 소모했을 뿐, 생성기를 사용하지 않은 버전은 35M의 메모리를 소모하여 직접적으로 10여 배의 차이가 났으며, 클수록 양적 차이가 매우 뚜렷하다.그래서 대신은 생성기를 PHP에서 가장 과소평가된 특성이라고 말한다.

생성기의 응용


다음은 생성기의 기본적인 응용 방식을 살펴보자.

빈 값 반환 및 중단


생성기는 당연히 빈 값을 되돌려 줄 수 있다. 직접 yield;어떤 값도 가지고 있지 않으면 빈 값을 되돌릴 수 있다.방법에서return을 직접 사용합니다.생성기의 계속 실행을 중단하는 데도 사용할 수 있습니다.다음 코드는\i=4입니다.때 되돌아오는 것은 빈 값, 즉 5를 출력하지 않는 것이다. (왜냐하면 우리가 되돌아오는 것은 i=4; 때 되돌아오는 것은 빈 값, 즉 5를 출력하지 않기 때문이다. (우리가 되돌아오는 것은 i+1이기 때문이다.)그리고 $i==7 때 return을 사용합니다.생성기의 계속적인 실행을 중단합니다. 즉, 순환은 최대 7까지만 출력되고 끝납니다.

//  
function test4()
{
    for ($i = 0; $i < 10; $i++) {
        if ($i == 4) {
            yield; //  null 
        }
        if ($i == 7) {
            return; //  
        }
        yield $i + 1;
    }
}

foreach (test4() as $t) {
    echo $t, PHP_EOL;
}


// 1
// 2
// 3
// 4

// 5
// 6
// 7

키 값 쌍으로 돌아가기


놀라지 마세요. 생성기는 정말 키 값이 형식에 대한 반복 가능한 대상을 되돌려 foreach에 사용할 수 있습니다. 그리고 문법은 매우 기억하기 쉽습니다: yield key = >value;수조 항목의 정의 형식과 똑같지 않은지 매우 직관적이고 이해하기 쉽다.

function test5()
{
    for ($i = 0; $i < 10; $i++) {
        yield 'key.' . $i => $i + 1;
    }
}

foreach (test5() as $k=>$t) {
    echo $k . ':' . $t, PHP_EOL;
}

// key.0:1
// key.1:2
// key.2:3
// key.3:4
// key.4:5
// key.5:6
// key.6:7
// key.7:8
// key.8:9
// key.9:10

외부 전송 데이터


Generator::send 방법을 통해 생성기에 값을 전달할 수 있습니다.전송된 이 값은 생성기 현재 yield의 반환값으로 간주됩니다.그리고 우리는 이 값에 따라 외부 조건에 따라 생성기의 실행을 중단할 수 있다.

function test6()
{
    for ($i = 0; $i < 10; $i++) {
        //  , send ,yield 
        $data = (yield $i + 1);
        if($data == 'stop'){
            return;
        }
    }
}
$t6 = test6();
foreach($t6 as $t){
    if($t == 3){
        $t6->send('stop');
    }
    echo $t, PHP_EOL;
}

// 1
// 2
// 3
상술한 코드는 이해하기 어려울 수 있지만, 주석의 줄을 기억하면 된다. (정상적으로 순환 값을 얻고, 외부send가 값을 가져오면 yield가 얻는 것은 외부에서 전해지는 값이다.)또한 변수는 yield의 값을 가져오려면 괄호로 묶어야 합니다.

문법


yieldfrom 문법은 사실 다른 교체 가능한 대상에서 하나하나 데이터를 얻고 생성기를 형성하여 되돌아오는 것을 가리킨다.코드 바로 보기

function test7()
{
    yield from [1, 2, 3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from test1();
}
foreach (test7() as $t) {
    echo 'test7:', $t, PHP_EOL;
}

// test7:1
// test7:2
// test7:3
// test7:4
// test7:5
// test7:6
// test7:1
// test7:2
// test7:3
// test7:1000
테스트 7 () 방법에서, 우리는 yieldfrom을 사용하여 각각 일반 그룹, 교체기 대상, 다른 생성기에서 데이터를 가져와 현재 생성기의 내용으로 되돌려줍니다.

작은 기쁨


생성기는count로 수량을 얻을 수 있습니까?


죄송합니다. 생성기는count로 수량을 얻을 수 없습니다.

$c = count(test1()); // Warning: count(): Parameter must be an array or an object that implements Countable
// echo $c, PHP_EOL;
생성기 수를 count로 가져오면 Warning 경고에 직접 보고합니다.직접 출력은 항상 1을 표시합니다.count의 특성 때문에 (강제로 수조로 변환하면 1을 표시합니다.)

생산기를 사용하여 피보나치 수열을 얻다


//  
function fibonacci($item)
{
    $a = 0;
    $b = 1;
    for ($i = 0; $i < $item; $i++) {
        yield $a;
        $a = $b - $a;
        $b = $a + $b;
    }
}

$fibo = fibonacci(10);
foreach ($fibo as $value) {
    echo "$value
"; }
이 코드는 설명이 많지 않고 매우 직관적인 코드이다.

총결산


생성기는 PHP의 숨겨진 보물로 메모리 절약뿐만 아니라 문법도 매우 간결하고 명확하다.우리는 방법 내부에서 되돌아오는 값을 저장하기 위해 하나의 그룹을 더 정의할 필요가 없다. 직접 yield에서 하나하나 되돌아오면 된다.실제 프로젝트에서는 충분히 시도해 볼 만하지만, 시도가 끝나면 친구들과 공유하는 것을 잊지 마세요. 대부분의 사람들은 이 특성을 정말 접하지 못했을 거예요!!
테스트 코드:github.com/zhangyue050…
이상은 PHP 생성기의 사용에 대한 상세한 내용입니다. PHP 생성기에 대한 더 많은 자료는 저희 다른 관련 글을 주목해 주십시오!

좋은 웹페이지 즐겨찾기