2016-07-16 15 views
4

Ich habe eine Funktion, die ein Objekt (in diesem Fall ein Hammerspoon Notify-Objekt) erstellt, und ich möchte dieses Objekt als Parameter an eine anonyme Funktion übergeben, die selbst ist ein Argument für einen Funktionsaufruf.Rufen Sie eine anonyme Funktion mit einer lokalen Variablen als Parameter

Das ist eine sehr komplizierte Erklärung, aber ich denke, ein Beispiel macht es ziemlich klar.

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 

Der Ausgang hiervon ist, dass n druckt die erste Zeit (hs.notify: Title (0x7fbd2b5318f8)) in Ordnung, aber ist nil das zweite Mal, innerhalb der anonymen Funktion, und es gibt einen Fehler aus: attempt to index a nil value (local 'n').

Diese Art von Sinn macht Sinn, weil ich es nie wirklich übergebe. Gibt es eine Möglichkeit, es zu übergeben? Die Unterschrift des hs.timer.doAfter Anruf ist: hs.timer.doAfter(sec, fn) -> timer (http://www.hammerspoon.org/docs/hs.timer.html#doAfter)

+0

Gibt es eine gute IDE oder einen statischen Codeanalysator? Wenn Sie die erste (oder alle) 'print (n)' Anweisung wegnehmen, würde eine gute IDE Sie warnen, dass Sie 'n' einen Wert zugewiesen haben, der nie benutzt wird, was Ihnen helfen würde, das Verstecken zu finden, das Kurt erklärt [Antwort] (http://stackoverflow.com/a/38407417/2226988). –

Antwort

8

Die Definition der anonymen Funktion schließt die Erklärung eines Arguments n benannt, die die variable n vom äußeren Umfang verbirgt. Die Funktionsdeklaration erstellt eine neue lokale Variable, die null ist, es sei denn, ein Argument wird tatsächlich an die Funktion übergeben, aber die Zeitgeberfunktion, die Ihre anonyme Funktion aufruft, erwartet nichts zu übergeben, so dass die Funktion lokal n bleibt.

Sie können es beheben, indem Sie einfach die Argumentdeklaration von der anonymen Funktion entfernen, aber die Verwendung von n innerhalb der Funktion beibehalten. Dann wird die n Variable aus dem äußeren Geltungsbereich erfasst, die den Wert von hs.notify(...) zurückgegeben hat.

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