5

我有一个创建对象的函数(在本例中为 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) -> timer:(http://www.hammerspoon.org/docs/hs.timer.html#doAfter

4

1 回答 1

9

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

您可以通过简单地从匿名函数中删除参数声明来修复它,但保留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
于 2016-07-16T03:26:02.723 回答