能否不创建个别函数而制作可折叠的变量?

我有一段代码,起始时只有少量变量,使用这些起始变量制作更多元素。

function new( x, y, width, height )
    local object = {}
    --border
    object.border = { x = x, y = y, width = width, height = height }
    --body
    object.body = { x = x+1, y = y+1, width = width-2, height = height-2 }
    --font
    object.font = {}
    object.font.size = (object.body.height+2)-(math.floor((object.body.height+2)/4)+1)
    object.font.height = love.graphics.setNewFont( object.font.size ):getHeight()
    --padding
    object.padding = {}
    object.padding.height = math.floor(object.border.height*(2/29))
    object.padding.width = object.padding.height*3
    --text
    object.text = { input = '' }
    object.text.centerHeight = math.ceil(object.body.y+((object.body.height-object.font.height)/2))
    object.text.left = object.body.x+object.padding.width+object.padding.height
    --backspacing
    object.backspace = {key = false, rate = 3, time = 0, pausetime = 20, pause = true}
    --config
    object.config = { active = true, devmode = false, debug = false, id = gui.id(), type = 'textbox' }
    gui.add(object)
    return object.config.id
end

我在中间部分修改一些内容时,整个代码就乱了,因为从我修改的那个变量开始直到底部的值都不相同。

local x = gui.get(2)
x.body.height = 50

我想知道是否有一种方式,可以重新定义这些变量,从它们开始一直到底部,而不需要:(a)为每个变量创建函数;(b)编辑函数中所需的参数。

如果没有,有没有其他有效的方法来实现这个目的?

编辑: 变量的结构如下:

border->body->padding->font

我需要一种方法,可以定义任何一个变量,以便接下来的变量也会改变,例如:

object.body.x = 15

这样它会从重新定义的变量开始折叠到底部:

body->padding->font

但这意味着我必须在编辑某个变量到底部时重复此过程,例如这样做是极其低效的,尤其是当我添加更多元素时。

例如:

--padding->font
object.padding.width = 5
object.font.size = object.padding.width+1
点赞
用户5352026
用户5352026

你可以使用元表,具体来说是 __newindex 字段:

(嗯,需要与 __index 字段相结合,但是呃)

function new(x, y, width, height )
    local object = {
        font = {}, padding = {}, text = {input=''}, -- 表本身是静态的
        -- 同样,我假设 text.input 会更改并且必须保持不变
    }
    -- 这里有更多静态数据(是的是的,我知道。代码有点丑,但是如果它能很好地运行...)
    object.config = { active = true, devmode = false, debug = false, id = gui.id(), type = 'textbox' }
    object.backspace = {key = false, rate = 3, time = 0, pausetime = 20, pause = true}
        object.border = { x = x, y = y, width = width, height = height }
    -- 从上面的变量计算必须进行的事情放在下面
    local border = object.border
    local function calculate()
        --border
        --body
        object.body = { x = border.x+1, y = border.y+1, width = border.width-2, height = border.height-2 }
        --font
        object.font.size = height-(math.floor(height/4)+1)
        object.font.height = love.graphics.setNewFont( object.font.size ):getHeight()
        --padding
        object.padding.height = math.floor(object.border.height*(2/29))
        object.padding.width = object.padding.height*3
        --text
        object.text.centerHeight = math.ceil(object.body.y+((object.body.height-object.font.height)/2))
        object.text.left = object.body.x+object.padding.width+object.padding.height
        --backspacing
        --config
    end
    calculate()
    local proxy = setmetatable({},{
        __index = object; -- proxy.abc 返回 object.abc(要获取宽度,请使用 proxy.border.width)
        __newindex = function(s,k,v)
            -- 在执行“proxy[k] = v”时触发
            -- 我假设您只会更改 x / y / width / height,因为其他属性是动态的。
            -- 执行“proxy.x = 123”与“object.border.x = 123” + 重新计算是相同的
            object.border[k] = v -- 实际应用更改
            calculate() -- 重新计算基于上述更改的其他属性
        end;
    })
    gui.add(object)
    return object.config.id
end

您可以运行如 proxy.x = 12 的代码来编辑 X 属性。所有值都将被重新计算。这并不是最好的方法,但您的代码有点麻烦,需要改进。_(但是,如果这可以正常工作,那就好)_

注意:您只能设置 x_、_y_、_widthheight_。但是您仍然可以通过旧的方式获取所有属性,例如 proxy.padding.width_。 **(请注意,proxy.x 不起作用。请使用 proxy.border.x)**

2016-02-12 20:46:44