「PHP/入門/関数とは」の版間の差分
削除された内容 追加された内容
→array_*関数の拡張: ln タグ: 2017年版ソースエディター |
→ジェネレター: ジェネレター関数は、値を返す代わりに、yieldで必要なだけの値を生成することを除けば、通常の関数と同じように見えます。 yieldを含む関数はすべてジェネレター関数です。 ジェネレター関数が呼び出されると、繰返し実行可能なオブジェクト(iterable型のオブジェクト)が返されます。 そのオブジェクトに対して反復処理を行うと (たとえば foreach ループで)、 PHP は値が必要になるたびにオブジェクトの反復処理用メソッドをコールし、 ジェネレターが値を返した時点でその状態を保存して、次の値が必要になったときに再開できるようにします。 生成する値がなくなったら、ジェネレターは単に終了し、呼出し元のコードは配列の値がなくなったときと同じように続行できます。 タグ: 2017年版ソースエディター |
||
420 行
関数は、自分の定義の中に自分を含めることができます。
;[https://paiza.io/projects/6l_BcluymbeRujHGTJiIuw?language=php 例]:<syntaxhighlight lang=php line highlight="9,17,22">
<?php
declare(strict_types=1);
448 行
echo 'comma3(ipow(10, 9)) --> ', comma3(ipow(10, 9)), PHP_EOL;
echo 'comma3(ipow(2, 32)) --> ', comma3(ipow(2, 32)), PHP_EOL;
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
460 ⟶ 458行目:
:2つの関数とも定義が再帰的なので、再帰的呼び出しで実装しています。
:再帰的呼出しは、終了条件を間違えると「無限再帰」に陥ってしまい、資源(この場合はスタック)を喰いつくすまで帰ってきません。
:アルゴリズムが再帰的な場合、再帰的呼出しを行う関数として実装するとコードは短くなりますが、PHPの処理系はtailrecのような最適化は行わないので、関数呼出しのオーバーヘッドが再帰の
=== ジェネレター ===
ジェネレター関数は、値を返す代わりに、<code>yield</code>で必要なだけの値を生成することを除けば、通常の関数と同じように見えます。
<code>yield</code>を含む関数はすべてジェネレター関数です。
ジェネレター関数が呼び出されると、繰返し実行可能なオブジェクト(<code>iterable</code>型のオブジェクト)が返されます。
そのオブジェクトに対して反復処理を行うと (たとえば foreach ループで)、 PHP は値が必要になるたびにオブジェクトの反復処理用メソッドをコールし、 ジェネレターが値を返した時点でその状態を保存して、次の値が必要になったときに再開できるようにします。
生成する値がなくなったら、ジェネレターは単に終了し、呼出し元のコードは配列の値がなくなったときと同じように続行できます。
;[https://paiza.io/projects/qQA7qDf386VLLzuUsbkEEg?language=php 例]:<syntaxhighlight lang=php line highlight=6>
<?php
declare(strict_types=1);
function gen_square() : iterable {
for ($i = 0; $i < 10; $i++) {
yield $i * $i;
}
}
foreach (gen_square() as $value) {
echo "$value\n";
}
var_export(array(...gen_square()));
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
0
1
4
9
16
25
36
49
64
81
array (
0 => 0,
1 => 1,
2 => 4,
3 => 9,
4 => 16,
5 => 25,
6 => 36,
7 => 49,
8 => 64,
9 => 81,
)
</syntaxhighlight>
ジェネレターは配列に似ていますが、配列は 要素数 × 要素1つあたりのサイズ のメモリーフットプリントを消費します。それに対しジェネレターは、<code>yield</code> で返す値は都度計算できるのでメモリー消費は配列に比べ小さくなります。
== コードキャラリー ==
|