読者です 読者をやめる 読者になる 読者になる

Life, Education, Death

プログラミング以外でも思ったことをつらつらと書きたい

クロージャーの使い方を少し聞かれたので調べてみた

まとめ

  • useで変数を指定する際に&をつけないと無名関数内で書き換えができない
  • useは面倒だけど、トラブルが減るので悪くない気がする

はじめて、PHPの無名関数を使っていたけど、意外と簡単に出来た

PHP5.3系からcreate_functionがなくても無名関数が作れるようになりました。
知り合いからJSでいう↓のようなコードはどう書くのか聞かれたので、試してみました。

function createNextValFunc(){
    var i=0
    return function(){
        i += 1
        return i
    }
}
var next = createNextValFunc()
alert(next())
alert(next())
alert(next())

関数を実行するたびに内部で保持している値がカウントアップされて、次の値が返される
関数を作る関数を定義してあります。PHPでやろうとすると↓のような感じになります。
そんなには変わらないですね。

function createNextValFunc(){
    $i = 0;
    return function() use ( &$i ){
        $i+=1;
        return $i;
    };
}

$next = createNextValFunc();
echo ' val: '.$next();
echo ' val: '.$next();
echo ' val: '.$next();

結果

val: 1 val: 2 val: 3

useで引数を使えるようにするときは値が参照ではなくコピーで渡されるようで
無名関数内で使いたいときは変数名の前に&をつけてあげないと書き換えが反映されません。

外部変数の値を書き換える必要がなければ、&は必要ありません。


useを使わないと外の変数に触れませんが、コードを読む際に宣言的になっていて変数の影響範囲がわかりやすくていい気がしてます。
useがあれば、巨大な無名関数などを作ったときに、たまたま外と同じ変数名を定義して挙動がおかしくなったりすることがないだろうし・・・。
まぁ見通しの悪い関数を定義すること自体が悪かもしれないが。