Почему Lua так трудно действительно копировать переменную по значению, а не только по ссылке?
Потому что то, что означает «копировать» таблицу, очень сильно зависит от того, что в этой таблице.
Сначала немного номенклатуры.Вы не ссылаетесь на «переменную»;вы получаете ссылку на таблицу .«Переменная» - это просто держатель для таких вещей, как число, строка или ссылка на таблицу.
Поэтому, когда вы говорите «действительно скопируйте переменную», вы на самом деле имеете в виду «копировать»стол."И ... это не просто.
Рассмотрим эту таблицу:
local tbl = {x = 5, y = {20}}
Если вы хотите скопировать эту таблицу, вы хотите, чтобы в поле y
новой таблицы была копиятаблицы, которую хранил старый?Или вы хотите, чтобы эта таблица была копией оригинала?
Ни один из ответов не является неправильным;какой из них вы хотите, полностью зависит от того, что вы хотите сделать.Но вы не можете слепо делать рекурсивные копии таблиц, потому что:
local tbl = {x = 5, y = {20}}
tbl._tbl = tbl
Эта таблица теперь хранит ссылку на себя .Попытка сделать слепую рекурсивную копию этой таблицы приведет к бесконечной рекурсии.Вы должны будете обнаружить, что таблица ссылается на себя, и, таким образом, новая таблица хранит ссылку на новую таблицу.И это становится еще более сложным:
local tbl = {x = 5, y = {20}}
tbl.z = tbl.y
Эта таблица теперь имеет два поля, которые ссылаются на одну и ту же таблицу.Если вы хотите иметь истинную копию этой таблицы, то копия должна понимать, что два поля ссылаются друг на друга, поэтому при копировании первого поля второе поле может ссылаться на новую копию, а не копировать ее снова.
И я даже не разбирался в метатаблицах и в гимнастике, с которой вы можете заниматься.Также это не включает обсуждение вещей, которые принципиально не копируются, как объекты пользовательских данных из API на основе Си.Если я сохраню результат io.open
в таблице, не будет механизма для копирования этого дескриптора файла.Итак, что должна делать ваша подпрограмма копирования?
Lua не имеет API-интерфейса копирования таблиц по умолчанию, чтобы убедиться, что вы сами потратите время, чтобы выяснить, насколько сложным должен быть ваш алгоритм копирования.