2011-11-15 8 views
6

Uczę się Lua i natknąłem się na koncepcję anonimowych funkcji. To interesujące, ale zastanawiałem się, jaką dodatkową zaletę zapewnia ponad nie anonimowymi funkcjami.Anonymous vs Non Anonymous functions Lua

Więc jeśli mam coś podobnego

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

Funkcja ta jest anonimowa, a jeśli mam

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

Funkcja nie jest anonimowy. Druga jest lepsza, ponieważ mogę ją nazwać, gdzie tylko chcę, a także wiem, co robię. Jaka jest zaleta anonimowych funkcji? Czy coś mi umyka?

+7

Masz go od tyłu. O wiele bardziej przydatnym modelem mentalnym jest traktowanie "funkcji f (...) ... końca" jako cukru syntaktycznego dla 'local f = function (...) ... end' i myślenie o funkcjach ogólnie jako obiektach zamiast statycznych bloków budulcowych twojego programu. Nie pytasz, dlaczego możesz używać literałów liczbowych bez podawania im wyszukanych angielskich nazw, prawda? – delnan

Odpowiedz

20

Szczerze mówiąc, nie ma czegoś takiego jak o nazwie funkcja w Lua. Wszystkie funkcje są w rzeczywistości anonimowe, ale mogą być przechowywane w zmiennych (które mają nazwę).

Podany funkcja składnia function add(a,b) return a+b end jest rzeczywiście syntactic sugar dla add = function(a,b) return a+b end.

funkcje są często wykorzystywane jako obsługi zdarzeń i decyzji, których biblioteka nie/nie wiem, najbardziej znanym przykładem jest table.sort() - za pomocą funkcji można określić kolejność sortowania:

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

Punktem jest to, że najprawdopodobniej nie będziesz potrzebował tej funkcji później. Oczywiście, można również zapisać funkcji do zmiennej lokalnej (ewentualnie) i użyć jej:

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

Aby uzyskać więcej informacji, przeczytaj ten section on functions in PiL.

4

Drugim przykładem jest równoważna
add = function(a,b) return a+b end
Tak naprawdę używasz funkcje anonimowe cały czas, w trywialnym sensie.

Jednak funkcje anonimowe mogą być znacznie bardziej przydatne w innych kontekstach. Na przykład za pomocą funkcji mutować inne funkcje (duszę programowania funkcjonalnego.)

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)) 

Zasadniczo można utworzyć nazwę dla każdej pojedynczej funkcji, jeśli chcesz, ale w sytuacjach, gdy rzucają wokół tak wiele funkcje jednorazowe, jest to wygodniejsze niż.