2016-07-16 20 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'に割り当てていることを警告します。 [答え](http://stackoverflow.com/a/38407417/2226988)。 –

答えて

8

匿名関数の定義は、外側の範囲からn変数を隠蔽n名前付き引数の宣言を含みます。関数宣言は、引数が実際に関数に渡されない限り、nilである新しいローカル変数を作成していますが、無名関数を呼び出すタイマー関数は何も渡すことを期待していないので、関数ローカルnはnilのままです。

匿名関数から引数の宣言を削除するだけで修正できますが、関数内ではnの使用を保ちます。次に、から返された値を持つ外部スコープからn変数を取得します。

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 
関連する問題