Lua метатабельный класс деструктор - PullRequest
2 голосов
/ 06 декабря 2011

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

-------------------------------------------------
-- Arrow class
-------------------------------------------------

local arrow = {}
local arrow_mt = { __index = arrow } -- metatable

function arrow.new(x, y) -- constructor
    local newArrow = {
        position = { x = x, y = y }
    }

    return setmetatable( newArrow, arrow_mt )
end

function arrow:remove()
    -- remove the object here
    -- self = nil dosent work
end

Ответы [ 2 ]

5 голосов
/ 06 декабря 2011

Как сказал Николь, как только переменная получает ссылку на ваш объект, сам объект не может управлять этой переменной (т. Е. Установить ее значение на nil ). На самом деле, это хорошая вещь - представьте, что кто-то где-то сохранил ссылку на ваш объект в локальной переменной. Внезапно в неизвестный момент он становится ссылкой nil (потому что он где-то уничтожен), и любой дальнейший доступ к нему приводит к ошибке.

Это облом, мне нужно немедленно уничтожить объект.

Вам действительно нужно уничтожить объект? Зачем? Правильно ли работает сборщик мусора Lua? Разве нет другого способа спроектировать отношения между объектами?

Например, в простейшем случае вы можете форсировать сборку мусора через collectgarbage("collect"). Сборка мусора очистит все объекты, на которые нет ссылок strong . Если вы действительно хотите, чтобы переменные исчезали, храните их в слабой таблице . Конечно, Lua будет выполнять сборку мусора автоматически, пока вы распределяете объекты (если вы не остановите это). Вы также можете изменить скорость сборки мусора .

1 голос
/ 06 декабря 2011

Вы не можете. Lua не C / C ++; он использует сборку мусора. Поэтому вы должны полагаться на сборку мусора; пользователь вашего объекта может контролировать, когда он уходит. Они сами должны отказаться от своих ссылок на него, когда закончат.

Так что, хотя вы можете иметь явное «новое» (хотя вы не должны называть это так), вы не можете получить явное «удаление». Разрушение произойдет, когда на объект больше не будет ссылаться.

...