Локальные переменные

Страницы: 1
RSS
Локальные переменные
 
В функцию в качестве аргумента приходит таблица data = { 'a', 'b', 'c', 'd', 'e' }
Для удобства я делаю следующее:

local var1 = data[1]
local var2 = data[2]
local var3 = data[3]
local var4 = data[4]
local var5 = data[5]

Вопрос состоит в следующем: при выходе из этой функции, что случится с переменными var1-5 и таблицей data? Будут ли они храниться в окружении данной функции или уничтожатся? Если data будут храниться, то не будет ли расточительством делать переменные var1-5? (т.к. это по сути копии таблицы data). Просто мне удобно использовать var1-5 (т.к. легче обращаться к значениям по имени переменной, а не по индексу в в таблице data), но в то же время опасаюсь, что это будет лишним засорением памяти.


// Появилась ещё идея, после ввода переменных var1-5 выполнить код: data = nil. Что скажете?
 
При выходе из функции переменные var1-5 будут уничтожены. С самой таблицей data нечего не случится.
Если в функции выполнить data = nil, где data - внешняя по отношению к функции переменная, то таблица будет уничтожена. Если data - это аргумент функции (по сути - её локальная переменная), то с внешней таблицей (переданной в функцию в качестве аргумента) ничего не случится.
Модификация переменных var1-5 никак не отразится на содержимом внешней таблицы data, за исключением ситуации, когда элементом таблицы data, в свою очередь является таблица. Тогда модификация ее элементов (полей) будет менять содержимое data (например, var4.code = 5 - меняет содержимое data[4].code)
 
Цитата
Алексей написал:
При выходе из функции переменные var1-5 будут уничтожены. С самой таблицей data нечего не случится.
Уточнение: под самой таблица data, подразумевается переменная, переданная в функцию в качестве аргумента. Что касается переменной, видимой внутри функции в качестве аргумента, то она является локальной и, соответственно, "живет" только пока функция выполняется. Как-то специально ее уничтожать для экономии памяти не нужно.
 
Цитата
Алексей написал:
При выходе из функции переменные var1-5 будут уничтожены.
А если такой код:
Код
local var_func

function func()
   local var = 'abc' -- Создаем локальную переменную
   
   function func_2()
      print(var)
   end
   
   var_func = func_2 -- сохраняем во внешнюю переменную созданную функцию
   
   -- Выход из функции, локальная переменная 'var' уничтожается.
end

func()

var_func() -- по сути запускаем ранее созданную функцию func_2

-- ВЫВОД: 'abc'
Если локальные переменные уничтожаются при выходе из функции, почему тогда мы сможем прочесть локальную переменную 'var'?
 
В lua нет прямого объявления глобальных переменных, но я для простоты понимания "внесу" в программу этот "оператор" для лучшего понимания Вами Вашего кода:
Код
global func, func_2

local var_func -- локальная переменная, время жизни которой - это время пока данный модуль находится в памяти. 
               -- Если не заморачиваться с выгрузкой модулей из памяти, то эта переменная существует пока исполняется программа (как и все глобальные), просто она не видима в других модулях.

func = function()
   local var = 'abc' -- Создаем локальную переменную
   
   func_2 = function()
      print(var)
   end
   
   var_func = func_2 -- сохраняем во внешнюю переменную созданную функцию
   
   -- Выход из функции, локальная переменная 'var' уничтожается.
end

func()

var_func() -- по сути запускаем ранее созданную функцию func_2

-- ВЫВОД: 'abc'
 
Вы создали объект (тип функция) "function()  print(var) end", в замыкании которого (по сути, в исходной настройке стека для вызова этой функции) сохранили строку 'abc' в качестве стартового значения теперь уже локальной для созданной функции переменной var.
Указатель на этот объект (функцию) вы сохранили в глобальной переменной func_2, затем значение этого указателя скопировали в локальную для модуля переменную var_func.
Когда завершилось выполнение функции, указатель на которую Вы сохранили в глобальной переменной func, стек этой функции выгрузился из памяти, а вместе с ним и выгрузилась из памяти переменная var.
Но, повторюсь, в стеке функции, указатель на которую сохранился в переменных func_2 и var_func, сохранилось значение var (а не указатель на нее), которое в ней хранилось на момент создания объекта - функции.
Дело в том, что при создании функции в ее объекте сохраняется не только сам ее код, но и ее стартовый стек, в котором сохраняются, кроме всего прочего, значения всех внешних по отношении к ней локальных переменных, использованных в ее коде.
Почитайте про "замыкания функций lua".
 
Цитата
Иван Джеммер написал:
Цитата
Если локальные переменные уничтожаются при выходе из функции, почему тогда мы сможем прочесть локальную переменную 'var'
Таким образом, вызывая func_2 (или var_func) Вы не читаете переменную var, а обращаетесь к копии её значения, сохраненной в стеке функции func_2
 
Цитата
Иван Джеммер написал:
В функцию в качестве аргумента приходит таблица data = { 'a', 'b', 'c', 'd', 'e' }
Для удобства я делаю следующее:

local var1 = data[1]
local var2 = data[2]
local var3 = data[3]
local var4 = data[4]
local var5 = data[5]

Вопрос состоит в следующем: при выходе из этой функции, что случится с переменными  var1-5  и таблицей  data ? Будут ли они храниться в окружении данной функции или уничтожатся? Если  data  будут храниться, то не будет ли расточительством делать переменные  var1-5 ? (т.к. это по сути копии таблицы  data ). Просто мне удобно использовать  var1-5  (т.к. легче обращаться к значениям по имени переменной, а не по индексу в в таблице  data ), но в то же время опасаюсь, что это будет лишним засорением памяти.


// Появилась ещё идея, после ввода переменных  var1-5  выполнить код:  data  = nil. Что скажете?
обращение через локальные переменные и через индексные в массиве отличается тем, что локальные - это копия элементов, а индексное значение - это указатель.
Если Вы в функции сделаете так:
var1=0
то привыходе из функцию таблица data не изменится
а если сделать так
data[1]=0
то при выходе в таблице первый элемент будет равен 0.
---------------------------
Что касается затрат памяти, то после завершения вызова, освободившуюся память соберет сборщик мусора.
---------------------------
Если Вы много раз обращаетесь к данным внутри функции, то использование локальных переменных будет быстрее.
-------------------------
Резюме: Делайте как удобно.
Страницы: 1
Читают тему
Наверх