Пара трюков OpenComputers
Здесь опишу такие штучки, которые могут потребоваться продвинутым OC-программистам (да и просто Луа-программистам).
Busy Idle
С помощью этого трюка можно делать довольно точные задержки, причём с длительностью менее тика.
local lastSleep = os.clock() local function sleep(t) local begin = os.clock() while os.clock() - begin < t do if lastSleep - os.clock() >= 3.5 then -- В конфигурации дефолтное значение = 5 секунд, ставим на 1.5 меньше для безопасности. os.sleep(0.05) -- Вынужденная задержка. lastSleep = os.clock() t = t - 0.05 end end end
Проверка по значению
Очень часто в моих программах нужно найти ключ, значение которого соответствует данному. Для этого я написал простую функцию:
local function isin(tbl, value) for k, v in pairs(tbl) do if v == value then return true, k end end return false end
На огромных массивах может и затормозить — скорость работы прямо зависит от длины массива.
Табличная магия
Рассмотрим этот на первый взгляд обычный пример кода:
local tbl1 = {"My", "super", "table", 42} local tbl2 = tbl1 tbl2[2] = "cool" for _, tbl in pairs({tbl1, tbl2}) do -- Напечатать значения таблиц for k, v in pairs(tbl) do print(k, v) end end
Разумно ожидать такое:
1 My 2 super 3 table 4 42 1 My 2 cool 3 table 4 42
1 My 2 cool 3 table 4 42 1 My 2 cool 3 table 4 42
Как видно, изменив значение в одной таблице, изменилась и другая.
Дело в том, что переменная хранит указатель на таблицу, а не саму таблицу. Соответственно, и tbl1, и tbl2 ссылаются на один и тот же массив.
На первый взгляд это кажется ненормальным. Как скопировать-то таблицу?
local function copy(tbl) if type(tbl) ~= "table" then return tbl end local result = {} for k, v in pairs(tbl) do result[k] = copy(v) end return result end
Но из этого можно извлечь очень полезное применение. Когда мы передаём таблицу в аргументы функции, массив не копируется, а даётся указатель на тот же самый. Поэтому можно сообразить такой код:
local function removeOddNums(tbl) for k, v in pairs(tbl) do if tonumber(v) and v % 2 == 1 then tbl[k] = nil end end end local table = {5, 26, 249586, 457139, 876, 42, 153} removeOddNums(tbl)
И он будет работать. Этим и объясняется, почему table.sort не возвращает таблицу. У меня не самое полезное применение, однако с помощью таблицы можно создавать "поинтеры", например, так: local numPtr = {42}, а в функциях использовать так: local value = numPtr[1]; numPtr[1] = 666. И уже использовать их в своих вычислениях.
Думаю, вы найдёте применение этим фокусам. Не самые очевидные моменты, однако иногда требуется.
The end.
- 5
9 комментариев
Рекомендуемые комментарии