2014-02-22 61 views
2

我無法理解以下內容。我有以下代碼:局部變量只在另一行聲明時才起作用

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) 

這應該抓住鍵盤當我按超級 + 標籤然後通過調用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是在一行中所定義,後來被分配一行。爲什麼我不能在同一行上做這件事?

+4

局部變量的範圍從**聲明後的第一個語句**開始,一直持續到包含該聲明的最內層塊的最後一個非void語句。 [手冊](http://www.lua.org/manual/5.2/manual.html#3.5) –

+0

有趣的是,本地抓取者抓取器= awful.keygrabber.run('...,因爲空格,註釋和';'是語句分隔符(但是,這會讓閱讀變得更加困難) –

回答

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。如果沒有以上,anil,無論函數是如何運行的次數:

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被充分評估爲止。

+2

即使沒有do-end塊,第一個'a'仍然存在,改變'g'打印'a'會顯示出來。 – lhf

+0

感謝您指點我已經改變了我的答案的結尾,以反映這一點,希望它更好 – Schollii

+0

你解釋了這個問題相當好,但我希望這個例子來證明這個問題,這個例子似乎工作而不是解決問題。 – siebz0r

相關問題