無名関数


無名関数

無名関数: 名前がないの関数。その代わりに、プログラミング言語によって特別なシンタクスを使う。

一般的に、そのシンタクスはラムダ式を使います。以下は様々なプログラミング言語でA+Bを計算(けいさん)する無名関数です。

C++ (C++11以後)

[](int a, int b) {
    return a + b;
}

C#

(a, b) => a + b

JavaScript

function(a, b) {
    return a + b;
}

PHP

function($a, $b) {
    return $a + $b;
}

使用

無名関数も色々あります。例えば、一般的なソートの関数を作りたかったら、順番はパラメーターにある無名関数に任せば、色んな順番出来ます:(a,b) => (a < b)で昇順(しょうじゅん)が出来て、(a,b) => (a > b)は降順(こうじゅん)になります。コールバックでも良く使います。

変数捕捉(へんすうほそく)

変数捕捉は無名関数で良くある問題ですが、たまに使用もあります。

例題:このJavascriptのコードのアウトプットは何?

var anonFuncs = [];

function createAnonFuncs() {
    for(var i = 0; i < 3; ++i) {
        anonFuncs[i] = function() {
            console.log(i);
        };
    }
}

function executeAnonFuncs() {
    for(var i = 0; i < 3; ++i) {
        anonFuncs[i]();
    }
}

createAnonFuncs();
executeAnonFuncs();

正解

3
3
3

iの変数は補足されています。createAnonFuncsが終わる時に、iは3、そしてそれぞれの無名関数はconsole.log(i)をするですから、皆console.log(3)になりました。

解決

プログラミング言語毎で解決があります。例えば、PHPはclosureという物を使います。
以上の場合は、このままで解決が出来ます:

var anonFuncs = [];

function createAnonFuncs() {
    for(var i = 0; i < 3; ++i) {
        anonFuncs[i] = createSingleAnonFunc(i);
    }
}

function executeAnonFuncs() {
    for(var i = 0; i < 3; ++i) {
        anonFuncs[i]();
    }
}

function createSingleAnonFunc(i) {
    return function() {
        console.log(i);
    }
}

createAnonFuncs();
executeAnonFuncs();

アウトプット

0
1
2

Javascriptは変数のスコープが関数用です。新しい変数を使って、別なスコープになります。