Mr_Bob Posted July 30, 2013 Share Posted July 30, 2013 В общем вот пример: function sdsssss(var) local var2= var var2[2] = "ssss" outputChatBox(var[1].." "..var[2]) --> "1 ssss" outputChatBox(var2[1].." "..var2[2])--> "1 ssss" end sdsssss({1,2}) Почему вторая строка меняется так же и в "оригинальной" таблице? Как выйти из этой ситуации (кроме цикла со вносом каждой строки в новую таблицу)? Link to comment
TEDERIs Posted July 31, 2013 Share Posted July 31, 2013 Во время присваивания значения с типом таблицы, в переменную заносится только адрес этой таблицы. Выйти из ситуации можно банально копированием таблицы. Например при помощи вот такой простой функции: function table.copy ( t ) local tbl2 = { } for k, v in pairs ( t ) do tbl2 [ k ] = v end return tbl2 end Link to comment
Mr_Bob Posted July 31, 2013 Author Share Posted July 31, 2013 Это понятно. А если вот передаю таблицу с сервера клиенту, на клиенте делаю следующее: function receiveNewStats(stats_table) client_stats_table = stats_table end Получается, что таблица stats_table все время висит в памяти клиента? Link to comment
Kernell Posted July 31, 2013 Share Posted July 31, 2013 В Lua переменная живёт пока: 1. на неё есть ссылки; 2. переменная не выйдет из области видимости. Если переменная в глобальной области видимости - то да, она постоянно будет висеть в памяти. Если ранее нигде область видимости не задавалась - то переменная автоматически становится глобальной. Link to comment
lil Toady Posted July 31, 2013 Share Posted July 31, 2013 В Lua переменная живёт пока: 1. на неё есть ссылки; 2. переменная не выйдет из области видимости.Если переменная в глобальной области видимости - то да, она постоянно будет висеть в памяти. Если ранее нигде область видимости не задавалась - то переменная автоматически становится глобальной. Это не совсем так. Принцип верен, но все немного сложнее, Луа работает не так как остальные языки. В Луа используется такой термин как среда (environment), _G - это ссылка на глобальную среду внутри глобальной среды (ссылка на саму себя), но каждая функция выполняется в своей среде. Мы знаем что среда - это лишь таблица, а следовательно, для каждой функции существует своя таблица, записи в которую заносятся оператором local. Для тех кто знаком с мета таблицами, понятнее будет так: local env = {} setmetatable ( env, { __index = _G } ) function f () end setfenv ( f, env ) Это то что делает Луа. Для тех кто не в курсе, __index метаметод действует следующим образом: Если в таблице не найдено значение, поиск ведется в __index таблице. А функцией setfenv можно поменять среду, сделав так что внутри функции будут недоступны даже глобальные переменные. Таким образом, не создавая ссылки на объект кроме локальной, даже выйдя из скоупа (зоны видимости), ссылка на объект будет хранится в среде, если в этой среде была создана другая функция, среда которой по дефолту будет ссылаться на вышестоящую. Пример: function a () local test = "boo" local b = function () outputChatBox ( test ) end addEventHandler ( "onPlayerJoin", getRootElement(), b ) end a() В данном случае, когда на сервер будет заходить игрок, всегда будет выводиться в чат "boo", не смотря на то что и переменная test и функция boo были локальными. Ссылку на функцию b хранит МТА, а к функции b присвоена среда которая зависит от среды фукции a. З.Ы. Каждый файл в ресурсе можно рассматривать как функцию, потому что на самом деле мта лишь загружает сожержимое файла в loadstring, которая возвращает функцию. Таким образом и для каждого файла может существовать своя переменная. З.Ы.Ы. Это не описывают в уроках по Луа, может кому-нибудь будет интересно. Link to comment
TheNormalnij Posted July 31, 2013 Share Posted July 31, 2013 Определенно в закладки, очень интересно. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now