2016-07-16 48 views
4

我有一个函数可以创建一个对象(在本例中是一个Hammerspoon Notify对象),我想将这个对象作为参数传递给本身的匿名函数一个函数调用的参数。用局部变量调用一个匿名函数作为参数

这是一个非常复杂的解释,但我认为一个例子很清楚。

function main() 
    local n = hs.notify(...) 
    print(n)   -- `hs.notify: Title (0x7fbd2b5318f8)` 
    hs.timer.doAfter(1, function(n) 
     print(n)  -- nil 
     n:withdraw() -- error: attempt to index a nil value (local 'n') 
    end) 
end 

的这个输出是n打印精第一次(hs.notify: Title (0x7fbd2b5318f8)),但是nil所述第二时间,所述匿名函数的内部,并且引发一个错误:attempt to index a nil value (local 'n')

这种说法很有道理,因为我从来没有真正把它传入。有没有办法将它传入? 的hs.timer.doAfter呼叫的签名是:hs.timer.doAfter(sec, fn) -> timerhttp://www.hammerspoon.org/docs/hs.timer.html#doAfter

+0

是否有良好的IDE或静态代码分析器可供您使用?如果您拿走了第一个(或全部)'print(n)'语句,一个好的IDE会警告您,您已经为'n'分配了一个永远不会使用的值,这将帮助您检测Kurt在他的解释中隐藏的[应答](http://stackoverflow.com/a/38407417/2226988)。 –

回答

8

匿名函数的定义包括名为n一个参数,隐藏从外部范围的n变量的声明。函数声明创建了一个新的局部变量nil,除非实际将参数传递给该函数,但调用匿名函数的计时器函数不期望传入任何内容,因此函数本地n保持为零。

您可以通过简单地从匿名函数中删除参数声明来修复它,但在函数中保留n的用法。然后它将捕获外部示波器的n变量,该变量的值从hs.notify(...)返回。

function main() 
    local n = hs.notify(...) 
    print(n)   -- `hs.notify: Title (0x7fbd2b5318f8)` 
    hs.timer.doAfter(1, function() -- <== no argument 
     print(n)  -- nil 
     n:withdraw() -- error: attempt to index a nil value (local 'n') 
    end) 
end 
相关问题