2011-05-20 2 views
17

Как мне вызвать функцию, которую нужно вызывать над ее созданием? Я прочитал что-то о форвардных объявлениях, но Google в этом случае не помогает. Каков правильный синтаксис для этого?Вперед определить функцию в Lua?

Спасибо.

ответ

29

Lua - динамический язык, а функции - это своего рода ценность, которую можно назвать оператором (). Таким образом, вам не нужно пересылать декларацию функции так, чтобы убедиться, что переменная в области, когда вы ее называете, - это переменная, которую вы так считаете.

Это не проблема вообще для глобальных переменных, содержащих функции, поскольку глобальная среда является местом по умолчанию для поиска имени переменной. Однако для локальных функций вам необходимо убедиться, что локальная переменная уже находится в области действия в лексической точке, где вам нужно вызвать значение, которое она хранит, а также убедиться, что во время выполнения она действительно держит значение, которое можно вызвать ,

Например, здесь есть пара взаимно рекурсивных локальных функции:

local a,b 
a = function() return b() end 
b = function() return a() end 

Конечно, это также пример использования хвоста вызовы, чтобы позволить бесконечную рекурсию, что не делает ничего, но дело здесь является деклараций. Объявляя переменные с local перед тем, как либо функция, хранящаяся в ней, эти имена, как известно, являются локальными переменными в лексической области остальной части примера. Затем сохраняются две функции, каждая из которых ссылается на другую переменную.

+1

Хорошо, спасибо. Мне удалось выяснить это самостоятельно, но этот ответ был полезен, тем не менее. –

9

Вы можете переадресовать объявить функцию, объявив свое имя, прежде чем объявить фактическое тело функции:

local func1 
local func2 = function() 
    func1() 
end 
func1 = function() 
    --do something 
end 

Однако вперед декларации необходимы только при объявлении функции с локальной областью. Это, как правило, то, что вы хотите сделать, но Lua также поддерживает синтаксис более как C, в этом случае опережающее объявление не является необходимым:

function func2() 
    func1() 
end 
function func1() 
    --do something 
end 
+4

На самом деле, ваш первый пример не делает то, что вы думаете, потому что второй 'local func1' объявляет * новую переменную этого имени и оставляет первый' func1' потерянным и все еще установленным на 'nil'. – RBerteig

+0

oops good point, я исправлю это – jhocking

+1

Ваш второй пример тоже плох, потому что наивный вызов func2 снизу func1 будет работать, но не из-за какого-либо «прямого объявления». Скорее func1 объявлен в глобальной среде (_G), и когда func2 ищет func1, он проверяет _G. Это означает, что func1 объявляется до запуска func2 и, таким образом, когда он проверяет _G, он работает. Вызов вызова func2 сразу после определения func2 приводит к ошибке ... потому что func1 не объявлен/определен. – LuaWeaver

0

Тестирование под встраиваемой Lua в FreeSwitch, опережающее объявление не работает:

fmsg("CRIT", "It worked.") 
function fmsg(infotype, msg) 
    freeswitch.consoleLog(infotype, msg .. "\n") 
end 

результат:

[ERR] mod_lua.cpp: 203 /usr/local/freeswitch/scripts/foo.lua:1: попытка вызвать глобальную 'fmsg' (ниль значение)

Реверсирование порядка выполняется (duh).

0

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

lua entry thread aborted: runtime error: lua_redirect.lua:109: attempt to call global 'throwErrorIfAny' (a nil value)

Фрагмент кода -

... 
throwErrorIfAny() 
... 

function throwErrorIfAny() 
    ngx.say("request not allowed") 
    ngx.exit(ngx.HTTP_OK) 
end 

Учитывая некоторые другие ответы также отметил, что он не работает для них тоже, вполне возможно, что упреждающее объявление о Lua не работает с другими инструментами ,

PS: Он отлично работает, если я ранее использовал определение функции, а затем вызываю его после опекунов.

Смежные вопросы