Объявление функций Lua и ссылки с правильным именем - PullRequest
3 голосов
/ 24 декабря 2011

В чем разница между следующими скриптами Lua с точки зрения объема функций.Как бы это повлияло на необходимость require 'calculator' в каком-нибудь другом скрипте Lua.И как бы это было указано в, скажем, LuaState.getGlobal(function_name).Каково было бы его правильное имя функции?Также подходит любой комментарий о преимуществах / недостатках декларации.

A) Calculator.lua

function foo(n) 
   return n+1;
end

B) Calculator.lua

calc= {}
function calc.foo(n) 
  return n+1;
end

C) Калькулятор.Луа

function foo(n) 
   return n+1;
end
function calculator()
   calc = {}
   calc.foo=foo
   return calc
end

Ответы [ 2 ]

2 голосов
/ 24 декабря 2011

Не совсем ответ, но комментарий к семантике - в Lua вы не объявляете функцию, вы создаете ее.Функция становится доступной во время выполнения function(...) ... end.То, как оно доступно, зависит от того, где вы его храните.

Вы должны помнить, что:

function myfun(foo) print('foo') end

- это просто синтаксический сахар для:

myfun = function(foo) print('foo') end

Если выне делать ничего особенного, myfun становится глобальной переменной, хранящейся в глобальном состоянии (доступной через _G).Если вы скажете local myfun до фактического вызова function myfun() end, функция (фактически замыкание ) будет сохранена в локальной переменной и доступна только для области действия локальной переменной.

Если вы используете require, он просто находит файл и загружает его один раз.Он не делает ничего необычного с модулем, например, скрывает глобальные переменные и т. Д. Поэтому, если вы напишите function foo() end в своем модуле Calculator.lua, то вызов require 'Calculator' создаст функцию в глобальном foo, к которой вы можете получить доступ,LuaState.getGlobal("foo").Если вы создаете таблицу функций (шаг B ), вам необходимо выполнить 2 шага:

L.getGlobal("calc")   -- pushes the "calc" global (a table) to the stack
L.getField(-1, "foo") -- gets the "foo" field from the table 
2 голосов
/ 24 декабря 2011

Я не знаю, что именно вы подразумеваете под «областью действия» этих сценариев. Что именно делают эти сценарии, зависит от того, как они выполняются. Вы могли бы дать им другую среду, таким образом изменив то, что они считают «глобальными».

Итак, я объясню, что делает каждый из этих сценариев, исходя из предположения, что вы загружаете их с dofile, dostring или чем-то подобным. То есть вы применяете их в глобальной среде.

A)

Это создает единственную глобальную переменную foo, которая является функцией.

В)

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

С)

Это создает две глобальные переменные. foo - это функция. calculator также является функцией. Каждый вызов calculator приведет к перезаписи глобальной переменной calc. Новое значение calc будет таблицей с единственной записью с ключом foo, значение которого является копией того, что хранится в глобальной переменной foo.

Трудно сказать, каковы "преимущества" метода C , поскольку в этом нет смысла. Он создает две функции вместо одной, и эта вторая функция продолжает создавать новые таблицы.

B - это просто версия пространства имен для A . Общее ожидание с модулями Lua состоит в том, что включение их обычно создает некоторую таблицу, которая будет содержать все функции в этом модуле, чтобы избежать конфликтов имен с существующим глобальным состоянием. В этом отношении B может быть лучше. Но это в основном зависит от того, для чего этот скрипт будет использоваться.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...