2

簡単な例があります:

function func1(){
    return function (){
        return 1;
    };
}

しかし、それを自分の理由でどのように使用できるかは明確ではありません。func1() は、無名関数とまったく同じものを返すようです。しかし、私がこのように書くと:

echo func1();

...エラーが表示されます:

Catchable fatal error: Object of class Closure could not be converted to string in [file_name] on line [line]

クロージャ オブジェクト以外は何も取得できません。

var_dump(func1());
---------------------
object(Closure)[1]

ただし、これを実際に使用することはできません。無名関数が何を返すかに関係なく、常に同じオブジェクトが含まれます - object(Closure)[1]。(私はphp 5.3.3を使用しています)また、無名関数が func1() 内に返す値を格納する方法がわかりません。とにかく、それはより近いオブジェクトです。しかし、それをどのように使用するのでしょうか。

4

2 に答える 2

4

あなたの例では、への呼び出しの戻り値は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_10multiplier

また、 への呼び出しの各戻り値が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);

ただし、代わりにクロージャーを使用する利点は、データを非表示にできることです (この例では乗数など)。

于 2013-08-08T19:29:48.680 に答える
1

無名関数は、 などの関数のパラメーターとして使用すると便利ですarray_filter()こちらのドキュメントを参照してください。

また、これを試してみました:

$x = func1();
echo $x();

その場合、結果は定義方法によって異なりますfunc1

于 2013-08-08T17:54:53.483 に答える