Объявление глобальной переменной внутри функции в LUA

#lua

#lua

Вопрос:

У меня есть функция, внутри которой я объявил глобальную переменную obs , внутри функции и присвоил некоторое значение.Если я хочу получить к ней доступ в каком-либо другом файле lua, выдается сообщение об ошибке: «попытка вызвать obs нулевое значение, что мне нужно сделать, чтобы получить к нему доступ?

Вот фиктивный код для нее

 //A.lua
function X()
obs = splitText(lk,MAXLEN)
end

//B.lua
function Y()
for i=1, #obs do      //error at this line
end
end
  

Комментарии:

1. Должно работать, если у вас есть оператор require поверх B.lua, который вызывает A.lua. И убедитесь, что вы вызываете функцию X() перед вызовом функции Y() .

2. О, и возможно, что SplitText доставляет nil

3. О, нет, нет. SplitText вообще не выдает NIL . На самом деле, есть ли какой-либо другой способ сохранить значение? Я просто не могу выполнить оператор require для A.lua (что-то, что я не могу объяснить здесь), но это будет невозможно с тем кодом, который у меня есть. Мне просто нужно найти способ сохранить это значение где-нибудь, к которому можно получить доступ в B.lua

4. Трудно понять ваш дизайн. У вас есть разные варианты, зависит от вашего дизайна. Вы можете вызвать X непосредственно из B или внутри Y. Может быть, лучше вернуть obs в X, чтобы вы могли вызвать X в Y и использовать возвращаемое значение. Вы также можете передать функцию X в качестве аргумента функции Y.

5. Вы также можете записать файл, в котором вы храните obs, и прочитать его в B, но я думаю, что это был бы худший способ 🙂

Ответ №1:

Есть несколько способов сделать это. С вашей текущей настройкой вы могли бы сделать это:

a.lua

 function x()
    -- _G is the global table. this creates variable 'obs' attached to
    -- the global table with the value 'some text value'
    _G.obs = "some text value"
end
  

b.lua

 require "a"
function y()
     print(_G.obs); -- prints 'some text value' when invoked
end

x(); y();
  

Заполнение глобальной таблицы обычно является ужасной идеей, поскольку любой скрипт в любом другом месте потенциально может перезаписать значение, обнулить переменную и т. Д. Гораздо лучшим способом imo было бы, чтобы ваш a.lua возвращал свою функциональность в таблицу, которую вы можете записать в файлы, которые этого требуют. это позволит вам определить функцию-получатель для возврата переменной obs, подключенной непосредственно к вашей функциональности a.lua в ее текущем состоянии.

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

a.lua

 local obs_
function x()
    obs_ = "some text value"
end

function get_obs()
    return obs_
end

return { x = x, obs = get_obs }
  

b.lua

 local a = require "a"
function y()
    print(a.obs())
end


a.x()
y()
  

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

a.lua

 -- this will attach functions a_x and a_get_obs() to the global table
local obs_
function _G.a_x()
    obs_ = "some text value"
end

function _G.a_get_obs()
    return obs_
end
  

b.lua

 -- ignore this require, i'm assuming your framework has some other way loading
-- a.lua that i can't replicate
require "a"

function y()
    print(_G.a_get_obs())
end


_G.a_x()
y()
  

Комментарии:

1. Проблема в том, что по какой-то причине я не могу требовать «a» вверху

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

Ответ №2:

Помните, что некоторые программы Lua внутри других программ (Garry’s Mod, World of Warcraft, Vera, Domoticz) используют _ENV вместо _G, чтобы ограничить область их действия. Таким образом, глобальные переменные должны быть:

 _ENV.variable = 1
  

вместо:

 _G.variable = 1
  

Причина, по которой это происходит, заключается в том, что разработчик хочет ограничить стандартную библиотеку Lua, чтобы избежать доступа пользователя к таким методам, как: os.exit() .

Чтобы узнать, используется ли _ENV вместо _G , распечатайте его, и если он возвращает таблицу вместо nil, скорее всего, он используется. Вы также можете протестировать следующий фрагмент:

 print(getfenv(1) == _G)
print(getfenv(1) == _ENV)
  

Где для печати true используется тот, который вы используете.