Анонимные vs не анонимные функции Lua
Я изучаю Lua и столкнулся с концепцией анонимных функций. Это интересно, но мне было интересно, какое дополнительное преимущество он предоставляет по сравнению с не анонимными функциями.
Итак, если у меня есть что-то вроде
function(a,b) return (a+b) end
функция анонимна, и если у меня есть
function add(a,b) return (a+b) end
функция не является анонимным. Второе лучше, потому что я могу называть его, где хочу, и я также знаю, что делает моя функция. Так что преимущество анонимные функции? Я что-то упускаю?
2 ответов
честно говоря, нет такой вещи, как функция in Lua. Все функции на самом деле анонимны, но могут храниться в переменных (которые имеют имя).
на имя функции синтаксис function add(a,b) return a+b end
на самом деле синтаксический сахар на add = function(a,b) return a+b end
.
функции часто используются в качестве обработчиков событий и решений, которые библиотека не может знать, Самый известный пример table.sort()
- используя вашу функцию, вы можете укажите порядок сортировки:
people = {{name="John", age=20}, {name="Ann", age=25}}
table.sort(people, function (a,b) return a.name < b.name end)
дело в том, что, скорее всего, вам не понадобится функция позже. Конечно, вы также можете сохранить функцию в (возможно, локальную) переменную и использовать это:
local nameComparator = function (a,b) return a.name < b.name end
table.sort(people, nameComparator)
для получения дополнительной информации, прочитайте эту раздел о функциях в PiL.
второй пример эквивалентен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))
в принципе, вы можете создать имя для каждой отдельной функции, если хотите, но в ситуациях, когда вы бросаете так много одноразовых функций более удобно не делать этого.