Согласно справочнику Lua, к которому вы всегда должны обращаться, прежде чем задавать здесь вопрос, setmetatable(tbl, nil)
удалит метатаблицу таблицы tbl
, если исходная метатаблица tbl не будет защищена. Или, лучше сказать, удаляет не метатаблицу, а ссылку на нее. Таблица, которая служила метатаблицей, конечно, не будет удалена, пока на нее есть другие ссылки.
Прежде чем вы спросите людей, работает ли простой вызов функции, попробуйте сами. Вы можете использовать https://www.lua.org/cgi-bin/demo или любой другой интерпретатор Lua, и вы получите ответ за секунды, не привлекая никого.
Запуск этого кода:
setmetatable({}, false)
or
setmetatable({})
приведет к
ввод: 1: неверный аргумент # 2 для 'setmetatable' (ожидается ноль или таблица)
Теперь вы знаете, что нельзя ввести false и нужно явно ввести nil.
Чтобы проверить эту __metatable вещь, которую вы бы прочитали в справочном руководстве, вы можете попробовать этот код
local tbl = setmetatable({}, {__metatable = true})
setmetatable(tbl, nil)
В результате получается следующий результат:
ввод: 2: невозможно изменить защищенную метатаблицу
Ко второй части вашего вопроса:
tbl = nil не будет удалять таблицу, на которую ссылается tbl. Он удалит только ссылку на него.
local a = {}
local b = a
b = nil
print(a)
а по-прежнему является таблицей. Вы удалили только одну из его ссылок.
Если ссылки не осталось, сборщик мусора может собрать таблицу.
setmetatable(tbl, {})
установит ссылку на таблицу, возвращаемую конструктором таблиц {}
, и сохранит эту ссылку где-нибудь в недрах tbl
.
Если tbl
была последней ссылкой на эту таблицу, в какой-то момент она будет собрана как мусор. Тогда, конечно, единственная ссылка на таблицу, которую вы установили как метатаблицу, также исчезнет, и она также будет удалена.
Если вы сделаете что-то подобное:
local a = {}
local b = setmetatable({}, a)
, a = nil
не удаляет метатаблицу b
Так что да, он удалит обе таблицы, если не останется другой ссылки ни на одну из них.
person
Piglet
schedule
09.09.2016