2011-11-15 27 views
6

私はLuaを習っており、匿名関数の概念に遭遇しました。興味深いですが、私はそれが非匿名の機能よりもどのような利点があるのか​​疑問に思っていました。匿名と非匿名の関数Lua

だから私は

function(a,b) return (a+b) end 

のようなものを持っている場合、関数は匿名で、私は

function add(a,b) return (a+b) end 

を持っている場合、関数は非匿名です。私はそれが私が欲しいとどこでも私はそれを呼び出すことができると私はまた、私の機能が何をしているか知っているので、2番目の方が良いだから、無名関数の利点は何ですか?私はここに何かを逃していますか

+7

あなたはそれを後に持っています。はるかに有用なメンタルモデルは 'ローカルf = function(...)... end'の構文的な砂糖として' function f(...)... end'を扱い、一般的にオブジェクトをオブジェクトとして考えるあなたのプログラムの静的ビルディングブロックの数。数字のリテラルを最初に精巧な英語の名前を付けることなく使うことができるのはなぜですか? – delnan

答えて

20

ルアにはという名前のというものはありません。すべての関数は実際には匿名ですが、変数(名前を持つ)に格納することができます。

という名前機能構文function add(a,b) return a+b endは実際にadd = function(a,b) return a+b endためsyntactic sugarです。

people = {{name="John", age=20}, {name="Ann", age=25}} 
table.sort(people, function (a,b) return a.name < b.name end) 

ポイント:あなたの関数を使用して、あなたはソート順を指定することができます -

機能は、多くの場合、イベントハンドラとして、ライブラリは/最も有名な例はtable.sort()され、知ることはできませんしない意思決定のために使用されていますおそらく後でその機能を必要としないことでしょう。もちろん、あなたも(おそらくローカル)関数を変数に保存することができますし、それを使用します。詳細については

local nameComparator = function (a,b) return a.name < b.name end 
table.sort(people, nameComparator) 

を、このsection on functions in PiLをお読みください。

4

第二の例は、だから、本当にあなたが些細な意味では、無名関数のすべての時間を使用している
add = function(a,b) return a+b end
に相当します。

しかし、匿名関数は他のコンテキストではるかに役立ちます。例えば、他の機能を変異させる(関数型プログラミングの魂を。)関数を使用して

function make_version_with_n_args (func, n) 
    if n == 1 then 
     return function (x) return x end 
    else 
     return function (x, ...) 
      return func (x, make_version_with_n_args (func, n-1)(...)) 
     end 
    end 
end 

add_four = make_version_with_n_args (function (a, b) return a+b end, 4) 

print (add_four(3, 3, 3, 3)) 

add_sizes = {} 
for i = 1, 5 do 
    add_sizes[i] = make_version_with_n_args(function (a, b) return a+b end, i) 
end 

func_args = {} 
for i = 1, 5 do 
    func_args[#func_args+1] = 2 
    print (add_sizes[i](unpack(func_args))) 
end 

function make_general_version (func) 
    return function (...) 
     local args = {...} 
     local result = args[#args] 
     for i = #args-1,1,-1 do 
      result = func(args[i], result) 
     end 
     return result 
    end 
end 

general_add = make_general_version (function (a, b) return a+b end) 

print (general_add(4, 4, 4, 4)) 

することは基本的に、あなたがしたい場合はすべての単一の関数の名前を作成していますが、非常に多くの周りに投げている状況ですることができます一度だけの機能ではないので、より手軽にです。