Анонимные и не анонимные функции Lua - PullRequest
7 голосов
/ 15 ноября 2011

Я изучаю Lua и натолкнулся на концепцию анонимных функций.Интересно, но мне было интересно, какое дополнительное преимущество это дает по сравнению с неанонимными функциями.

Итак, если у меня есть что-то вроде

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

Функция анонимна, а если у меня есть

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

Функция не анонимна.Второе лучше, потому что я могу назвать его где угодно, и я также знаю, что делает моя функция.Так в чем же преимущество анонимных функций?Я что-то здесь упускаю?

Ответы [ 2 ]

22 голосов
/ 15 ноября 2011

Если честно, в 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 .

4 голосов
/ 15 ноября 2011

Второй пример эквивалентен
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))

По сути, вы можете создать имя для каждой отдельной функции, если хотите, но в ситуациях, когда вы бросаететак много разовых функций, удобнее не делать .

...