lua -> как изменить эти аргументы, чтобы они были const, или что мне делать? - PullRequest
2 голосов
/ 08 мая 2019

все!

Я пришел сюда, потому что у меня есть одна проблема, которая давала мне покоя довольно долго. Я использую движок love2d в качестве «графического» дополнения к сценариям lua, но эта проблема относится к типу lua (я думаю, по крайней мере).

У меня есть функция:

createNew_keepOld = function (oldImgData, oldImgDraw)
    local newImgData = oldImgData --I am assigning old value to another variable
    local newImgDraw = oldImgDraw --I am doing the same thing as with data 

    for x = 0, newImgData:getWidth()-1 do
        for y = 0, newImgData:getHeight()-1 do
            local r, g, b, a = newImgData:getPixel(x, y)
            r = 2*r
            g = 2*g
            b = 0.5*b
            a = 2*a
            newImgData:setPixel(x, y, r, g, b, a)
        end
    end

    newImgDraw:replacePixels(newImgData)

    return newImgData, newImgDraw
end

Когда этот код заканчивается, я получаю нужное мне изменение, но не ГДЕ, где я этого хочу. Я просто хочу создать две новые переменные, которые будут хранить данные и изображения объектов. Но, в процессе, оригинальное изображение изменяется.

Есть ли способ объявить:

name = function (const param, const param)

    return some_things
end

Чтобы получить нужный вывод без изменения оригинального материала? Или есть проблема с моим кодом, которую я не вижу?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 08 мая 2019

На самом деле природа этой проблемы и в Love2D, и в Lua.В любом случае.

Цитата из Справочное руководство Lua 5.3 :

Таблицы, функции, потоки и (полные) значения пользовательских данных являются объектами: переменные на самом деле не содержатэти значения, только ссылки на них.Присваивание, передача параметров и возврат функций всегда манипулируют ссылками на такие значения;эти операции не подразумевают какого-либо копирования.

Большинство типов из Love2D относятся к типу userdata Lua, поэтому при передаче их в вашу функцию вы фактически передаете ссылку на них, следовательно, вы изменяете «старые» версии в самом конце.Эти типы обычно имеют функции, предназначенные для их копирования.

ImageData есть, а Image - нет, но вы можете сделать следующее:

createNew_keepOld = function (oldImgData, oldImgDraw)
    local newImgData = oldImgData:clone()

    for x = 0, newImgData:getWidth()-1 do
        for y = 0, newImgData:getHeight()-1 do
            local r, g, b, a = newImgData:getPixel(x, y)
            r = 2*r
            g = 2*g
            b = 0.5*b
            a = 2*a
            newImgData:setPixel(x, y, r, g, b, a)
        end
    end

    local newImgDraw = love.graphics.newImage(newImgData, oldImgDraw:getFlags())

    return newImgData, newImgDraw
end

Обратите внимание, что я создал совершенно новый Image на основе скопированных ImageData и флагов изображений из старого.

2 голосов
/ 08 мая 2019

В Lua, когда вы создаете переменную, равную значению таблицы, вы не копируете и не дублируете эту информацию.Новая переменная просто указывает на те же значения, что и другая переменная.

Пример:

tbl1 = {}
tbl2 = tbl1

tbl2[1] = 1

print(tbl1[1])

Чтобы создать newImgData на основе oldImgData, вам необходимо предварительно сформировать глубокуюcopy:

function deepcopy(orig)
    local orig_type = type(orig)
    local copy
    if orig_type == 'table' then
        copy = {}
        for orig_key, orig_value in next, orig, nil do
            copy[deepcopy(orig_key)] = deepcopy(orig_value)
        end
        setmetatable(copy, deepcopy(getmetatable(orig)))
    else -- number, string, boolean, etc
        copy = orig
    end
    return copy
end

Ресурс для копирования таблицы: Lua-Users Wiki: Copy Table

Это решение работает только с типом table, оно не будет работать дляuserdata

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...