最新の PHP: ジェネレーターと例

WBOY
リリース: 2016-06-20 12:25:58
オリジナル
835 人が閲覧しました

コンセプト

簡単に言うと、PHP のジェネレーターは特殊なイテレーター (Iterator) ですが、通常、計算されたもの全体を反復する標準の PHP イテレーターとは異なります。データはメモリ内に設定され、ジェネレータは貴重なシステム メモリを占有することなく、次の値を動的に計算して引き渡すことができます。ジェネレーターは順方向のみの反復子であり、反復の開始後に巻き戻すことはできないため、同じジェネレーターを複数回反復することはできません。

yield

ジェネレーターを使用するには、yield キーワードを使用する必要があります。 yield は return と似ていますが、関数の実行を終了する代わりにループに値を提供し、ジェネレーター関数の実行を一時停止する点が異なります。

<?phpfunction myGenerator() {    yield 'value1';    yield 'value2';    yield 'value3';} foreach (myGenerator() as $yieldedValue) {      echo $yieldedValue, PHP_EOL;  }  
ログイン後にコピー

ジェネレーターが呼び出されると、このオブジェクトを反復処理できるオブジェクトが返されます (foreach ループなどを介して)。PHP はジェネレーター関数を実行します。値が必要になるたびに呼び出され、値を生成した後にジェネレーターの状態が保存されるため、次の値を生成する必要があるときに呼び出し状態を復元できます。値を生成する必要がなくなったら、ジェネレーター関数は単に終了することができ、ジェネレーターを呼び出したコードは、配列が反復処理されたかのように実行を続けることができます。

比較

乱数を生成する別の従来の例を見てください:

<?phpfunction makeRange($length) {    $dataset = [];    for ($i = 0; $i < $length; $i++) {        $dataset[] = $i;    }     return $dataset;} $customRange = makeRange(1000000);foreach ($customRangeas $i) {    echo $i, PHP_EOL;}
ログイン後にコピー

上の例では、makeRange 関数は数百万の整数のメモリ領域。 PHP ジェネレーターは上記の関数を実行することもでき、いつでも整数メモリを割り当てるだけで済みます。例を見てください。

<?phpfunction makeRange($length) {    for ($i = 0; $i < $length; $i++) {        yield $i;    }} foreach (makeRange(1000000) as $i) {    echo $i, PHP_EOL;}
ログイン後にコピー

キー/値ペア

yield は、配列と同様にキーと値のペアを生成することもできます。

<?php$input = <<<'EOF'1;PHP;Likesdollarsigns2;Python;Likeswhitespace3;Ruby;LikesblocksEOF; function input_parser($input) {    foreach (explode("\n", $input) as $line) {        $fields = explode(';', $line);        $id = array_shift($fields);         yield $id => $fields;    }} foreach (input_parser($input) as $id => $fields) {    echo "$id:\n";    echo "    $fields[0]\n";    echo "    $fields[1]\n";}
ログイン後にコピー

式のコンテキスト (代入式の右側など) で yield を使用する場合は、括弧を使用する必要があります。発言。

$data = (yield $value);
ログイン後にコピー

yield を引数なしで呼び出して NULL 値を生成し、自動キー名とペアにすることもできます。

ジェネレーターは値を返すことができず、値を返すとコンパイル エラーが発生することに注意してください。ただし、return null は有効な構文であり、ジェネレータの実行を終了します。

練習

実際には、ジェネレーターを使用してファイルを読み取って処理することもできますが、その間にビジネス ロジックを記述することもできますが、これは非常に面倒になります。ファイルを読み取るロジックが複数ある場合は、同様のメソッドを複数記述する必要があるため、ジェネレーターを使用すると、機能とサービスを分離できるだけでなく、メモリ使用量も削減できます。

    function read_file_line($file){        $handle=@fopen($file,'r');        if(!$handle){            throw new Exception("Can not read file!");        }         while(($line=fgets($handle))!==false){            yield $line;        }         if (!feof($handle)) {            throw new Exception('Error: unexpected fgets() fail');        }        fclose($handle);        return ;    }         foreach (read_file_line($file) as $row) {            //print_r($row);        }
ログイン後にコピー

CSV の読み取り方法を見てみましょう:

<?phpfunction getRows($file) {    $handle = fopen($file, 'rb');    if ($handle === false) {        throw new Exception();    }    while (feof($handle) === false) {        yieldfgetcsv($handle);    }    fclose($handle);} foreach (getRows('data.csv') as $row) {    print_r($row);}
ログイン後にコピー

send()

最後に、いくつかの追加 小さなジェネレーターは、send() 関数を通じて値を注入し、yield を通じて値を受け取ることができます。その後、他のジェネレータ関数の値と同様に使用できます。

function printer() {    while (true) {         // 通过 yield 语句返回注入的值        $string = yield;        echo $string;    }} $printer = printer();$printer->send('Hello world!'); // 输出 Hello world!
ログイン後にコピー

参考:

www.powerxing.com/php-review-generator/

www.cnblogs.com/ CraryPrimitiveMan/p/5130056.html

《モダン php》

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート