[解決済み] 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を更新してください。
ソースとさらなる読み物
関連
-
[解決済み】Notice: 非オブジェクトのプロパティを取得しようとしているエラー
-
[解決済み】不明なMySQLサーバーのホスト
-
[解決済み】pdo - 非オブジェクトのメンバー関数prepare()への呼び出し【重複】。
-
[解決済み】PHPの予期しないT_VARIABLEとは何ですか?
-
[解決済み] libapache2-mod-php7 パッケージの場所がわからない
-
[解決済み] 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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】SQLSTATE[42000]: 構文エラーまたはアクセス違反が発生しました。1064 SQL 構文にエラーがあります - PHP - PDO [重複]。
-
[解決済み】PHP 7.2 - Warning: count(): パラメータは配列かCountableを実装したオブジェクトでなければならない [解決済み]
-
[解決済み】 PHP 未定義関数の呼び出し
-
[解決済み】DateTimeクラスのオブジェクトを文字列に変換できない
-
[解決済み】未定義の関数mysql_query()をLoginで呼び出す【重複
-
[解決済み】メッセージ。Trying to access array offset on value of type null [重複]配列のオフセットにアクセスしようとしています。
-
[解決済み】PHP フェイタルエラー。未定義の関数mssql_connect()をコールしています。
-
[解決済み】mysqli::query(): mysqli をフェッチできない
-
[解決済み] PHPの配列を別の配列にコピーする関数はありますか?
-
[解決済み] PHP 未定義関数への呼び出し