[解決済み】PHPでyieldの意味は何ですか?
質問
最近、このコードに出会いました。
function xrange($min, $max)
{
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
こんなの見たことない
yield
というキーワードは初めてです。コードを実行しようとすると
パースエラー: 構文エラー、x行目に予期しないT_VARIABLEがあります。
では、これは何かというと
yield
キーワードは?これは有効なPHPなのでしょうか?また、有効である場合、どのように使用すればよいのでしょうか?
どのように解決するのですか?
とは
yield
?
は
yield
キーワード
は、ジェネレータ関数からデータを返します。
ジェネレータ関数の中心はyieldキーワードです。yield文は、関数の実行を停止して戻る代わりに、ジェネレータをループするコードに値を与えてジェネレータ関数の実行を一時停止することを除けば、最も単純な形でreturn文とほぼ同じに見えます。
ジェネレータ関数とは何ですか?
ジェネレータ関数は、事実上、よりコンパクトで効率的な方法で
イテレータ
. これは、関数 (
xrange
を実行します。
を計算し、返します。
値
間に
あなたは
ループさせる
:
function xrange($min, $max) {
for ($i = $min; $i <= $max; $i++) {
yield $i;
}
}
[…]
foreach (xrange(1, 10) as $key => $value) {
echo "$key => $value", PHP_EOL;
}
そうすると、次のような出力が得られます。
0 => 1
1 => 2
…
9 => 10
を制御することもできます。
$key
の中で
foreach
を使用することで
yield $someKey => $someValue;
ジェネレーター機能で
$someKey
に表示させたいものは何でもよい。
$key
と
$someValue
の値である。
$val
. 質問の例では、それは
$i
.
通常の機能とは何が違うのですか?
さて、なぜ PHP のネイティブな機能である
range
機能
を使えば、その出力を実現することができます。そしてその通りです。出力は同じでしょう。違うのは、そこに至る方法だ。
を使用する場合
range
PHP はこれを実行し、数値の配列全体をメモリ上に作成します。
return
その
配列全体
から
foreach
のループがその上を通過し、値を出力します。言い換えれば
foreach
は、配列そのものを操作することになります。そのため
range
関数と
foreach
は一度だけです。郵便で小包を受け取るようなものだと考えてください。配達員はあなたに荷物を渡して去っていきます。そして、あなたはパッケージ全体の包装を解き、中に入っているものを何でも取り出します。
ジェネレータ関数を使用すると、PHP は関数に踏み込み、終了に達するか、あるいは
yield
というキーワードがあります。キーワードに出会ったとき
yield
そして、その時の値を外側のループに返します。そして、ジェネレータ関数に戻り、元の場所に戻ります。あなたの
xrange
には
for
ループが実行され
$max
に到達しました。のようなものだと考えてください。
foreach
とジェネレータがピンポンをしているようなものです。
なぜそれが必要なのか?
明らかに、ジェネレータはメモリ制限を回避するために使用することができます。環境によっては
range(1, 1000000)
はスクリプトを致命的にしてしまいますが、ジェネレータを使えば同じようにうまく動作します。あるいは、Wikipediaによると
ジェネレータは生成された値を必要に応じて計算するので、一度に計算するのが面倒なシーケンスを表現するのに便利である。例えば、無限列やライブデータストリームなどです。
また、ジェネレーターはかなり高速であることが前提となっています。しかし、高速というのは、通常、非常に小さな数字での話であることを覚えておいてください。ですから、すべてのコードをジェネレーターを使用するように変更する前に、ベンチマークを行って、それが意味をなすかどうかを確認してください。
ジェネレータのもう1つのユースケースは、非同期コルーチンです。この場合
yield
キーワードは値を返すだけでなく、値を受け取ることもできます。これについての詳細は、以下のリンク先の2つの優れたブログ記事を参照してください。
いつから
yield
?
でジェネレータが導入されています。
PHP 5.5
. を使おうとすると
yield
それ以前のバージョンでは、キーワードに続くコードによってさまざまなパース・エラーが発生します。そのため、そのコードでパースエラーが発生した場合は、PHPを更新してください。
ソースとさらなる読み物
関連
-
[解決済み】Phpのincludeが機能しない? 関数がincludeされない
-
[解決済み] 警告:mysqli_fetch_array()は、パラメータ1がmysqli_resultであることを期待する、オブジェクトはで指定された。
-
[解決済み】PHPの予期しないT_VARIABLEとは何ですか?
-
[解決済み】file_get_contents( )が動作しない。
-
[解決済み] mysqli_fetch_assoc() は、パラメータ 1 が mysqli_result であることを期待し、boolean が与えられる [重複] 。
-
[解決済み] PHPで配列から要素を削除する
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] "お知らせ 未定義変数"、"Notice: Notice: 未定義のインデックス", "Notice:未定義のインデックス", "Notice."。PHPを使用した「未定義のオフセット
-
[解決済み】PHPの'foreach'は実際どのように動作するのですか?
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Fatal error: 未定義の関数 sqlsrv_connect() を呼び出した。
-
[解決済み】XAMPPエラー: www.example.com:443:0 サーバー証明書に、サーバー名と一致するIDが含まれていません。
-
[解決済み] $wpdb->update または $wpdb->insert を実行すると、引用符の前にスラッシュが追加される
-
[解決済み】Chrome net::ERR_INCOMPLETE_CHUNKED_ENCODING エラーが発生しました。
-
[解決済み】未定義のメソッド mysqli_stmt::get_result を呼び出す。
-
[解決済み] [Solved] Fatal error: メンバ関数 query() の null への呼び出し。
-
[解決済み】書き込みコンテキストでメソッドの戻り値を使用することができない
-
[解決済み] mysqli_fetch_assoc() は、パラメータ 1 が mysqli_result であることを期待し、boolean が与えられる [重複] 。
-
[解決済み】MySQLのカラム数が1行目の値数と一致しない【非公開
-
[解決済み】警告: file_get_contents(): https:// ラッパーがサーバー構成ですべて無効になっています。