局部变量仅在另一行上声明时才起作用

时间:2014-02-22 19:54:44

标签: lua awesome-wm

我无法理解以下内容。我有以下代码:

awful.key({ "Mod1" }, "Tab",
    function (c)
        local grabber = awful.keygrabber.run(
            function(mod, key, event)
                if grabber == nil then
                    naughty.notify({ text="nope"})
                end
                awful.keygrabber.stop(grabber)
                return
            end)
    end)

当我按 super + Tab 然后通过调用stop方法释放键盘焦点时,这应该会抓住键盘。但是grabber变量似乎是nil。起初我认为这是一个范围问题,所以我删除了local,这是有效的。但是我觉得这不是解决这个问题的方法。

在弄乱它之后我发现它有效:

awful.key({ "Mod1" }, "Tab",
    function (c)
        local grabber
        grabber = awful.keygrabber.run(
            function(mod, key, event)
                if grabber == nil then
                    naughty.notify({ text="nope"})
                end
                awful.keygrabber.stop(grabber)
                return
            end)
    end)

唯一的区别是变量grabber在一行上定义,稍后分配一行。为什么我不能在同一条线上这样做?

1 个答案:

答案 0 :(得分:4)

声明

local a = expr

其中expr可以是任何Lua表达式,只有在计算表达式后才会创建本地a。在此之前,local a不存在。如果表达式使用名为a的变量,则变量将从下一个“级别”获取。参见Lua ref的2.6节,它很简短,并提供了对此的更多见解。但这意味着如果你有

a = 123
local b = 456
local c = c + b

第三行将无法执行,因为c右侧的=尚不存在,因此它是nilb确实存在,尽管它是本地的。同样,在

local a = f()

如果f()使用a,则Lua会查找高于该行的a,因为它尚未创建local a。如果上面没有,a将为nil,无论该函数运行多少次:

do 
    local a = 1
    function g() a=a+1 end -- modifies the above local a ("upvalue")

    local a = function() return a+1 end -- a+1 uses the first local a
    -- a is now a local function, using the first local a 

    print(a()) -- prints 2
    g() -- increases the external a
    print(a()) -- prints 3
end

因此,声明本地与使用它们的函数是关键的,并且本地不存在(甚至是“隐藏”前一个本地的本地),直到expr被完全评估。