あなたの例では、への呼び出しの戻り値はfunc1
関数 (より具体的には a Closure
) です。あなたが得ているエラーは、php がこのオブジェクトを文字列に変換できないことが原因です。クロージャーによって返された値を出力したい場合は、それを呼び出す必要があります。
function func1() {
return function () {
return 1;
};
}
$f = func1(); // Create the closure
echo $f(); // Calls the closure
この例は単に関数を返す関数であり、クロージャーを他のファーストクラス関数と区別するものを示していません。つまり、クロージャーにはその作成に固有の状態を含めることができます。つまり、同じコードから、アクセスできるデータが異なる関数を生成できます。
次の簡単な例を考えてみましょう:
function multiplier($m) {
return function ($v) use ($m) {
return $v * $m;
};
}
$mult_5 = multiplier(5);
echo $mult_5(5); // prints 25
$mult_10 = multiplier(10);
echo $mult_10(5); // prints 50
繰り返しますが、これは非常に些細な例ですが、いくつかの重要なことを示しています。最初に、関数を 1 つだけ定義しましたが、この関数を呼び出すことで、呼び出し時にパラメーターを変更するだけで、似ているが異なる 2 つの関数を生成できました。また、関数にはそれぞれ独自の「状態」があることを考慮してください。私が名前を付けた関数の場合、$mult_5
それ自身の内部$m
値がであり、それが関数の値5
とは異なることを知っています。これらのそれぞれの値は関数に渡され、その関数は完了しましたが、値は返された関数/クロージャに残ります。$m
$mult_10
multiplier
また、 への呼び出しの各戻り値がmultiplier
ファースト クラス関数であることも注目に値します。つまり、一般化された関数 ( などmultiplier
) を記述し、それらを使用して、より具体的な関数を「オンザフライ」で生成できます。プログラムの現在の環境/状態に適しています。
OOP に精通している場合、上記の例は OOP を使用して簡単に書き直すことができます。
class Multiplier {
protected $m;
public function __construct($m) {
$this->m = $m;
}
public function multiply($v) {
return $v * $this->m;
}
}
$mult_5 = new Multiplier(5);
echo $mult_5->multiply(5); // prints 25
$mult_10 = new Multiplier(10);
echo $mult_10->multiply(5); // prints 50
...そして、これは非常に主観的ですが、クロージャーのより簡潔な構文を好みます。
または、より一般的な関数を使用して開始することもできます。
function multiplier($a, $b) {
return $a * $b;
}
echo multiplier(5, 5);
echo multiplier(5, 10);
ただし、代わりにクロージャーを使用する利点は、データを非表示にできることです (この例では乗数など)。