PHP のジェネレーターについて理解しましょう

藏色散人
リリース: 2023-04-09 16:42:02
転載
3677 人が閲覧しました

推奨: "PHP ビデオ チュートリアル "

ジェネレーターとは

PHP 5.5 以降、PHP には新しい機能が追加されました。ジェネレーター 、中国語では Generator と翻訳されます。ジェネレーターはオブジェクトの反復を実装するために簡単に使用できます。小さな公式の例から始めましょう。

xrange

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();
}
ログイン後にコピー

ここで、$numGenerator のオブジェクトです。ここには、validcurrentnext という 3 つのメソッドが表示されます。関数が実行され、後で 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 の戻り値を返すことができます。

その他のジェネレーター メソッド

Generator::key()

yield には、yield $id => $value を使用できます。 、つまり、key メソッドを通じて $id を取得でき、current メソッドは $value を返します。

Generator::rewind()

このメソッドは、ジェネレーターの実行を再開し、コンテキストを保存するのに役立ちます。同時に、最初の yield## を返します。 # コンテンツを返します。 send メソッドが初めて実行されると、rewind が暗黙的に呼び出されます。

Generator::throw()

このメソッドはジェネレーターに例外をスローします。

追記

yield PHP 5.5 の新機能として、データを効率的に反復する新しいメソッドを使用します。同時に、yield を使用してコルーチンを実装することもできます。

以上がPHP のジェネレーターについて理解しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!