Referenzen
The Go Programming Language Specification
Function types
A Funktionsart die Menge aller Funktionen mit den gleichen Parameter und Ergebnistypen bezeichnet.
FunctionType = "func" Signature .
Signature = Parameters [ Result ] .
Result = Parameters | Type .
Parameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = ParameterDecl { "," ParameterDecl } .
ParameterDecl = [ IdentifierList ] [ "..." ] Type .
Function declarations
A bindet Funktionsdeklaration einen Identifikator, den Namen der Funktion, auf ein Funktion.
FunctionDecl = "func" FunctionName Signature [ Body ] .
FunctionName = identifier .
Body = Block .
Function literals
A Funktionsliteral stellt eine anonyme Funktion. Es besteht aus einer Spezifikation des Funktionstyps und eines Funktionskörpers.
FunctionLit = FunctionType Body .
Funktionsliterale sind Schließungen: sie Variablen in eine umgebende Funktion definiert beziehen. Diese Variablen werden dann zwischen der Umgebungsfunktion und dem Funktionsliteral gemeinsam genutzt, und sie bleiben als erhalten, solange sie zugänglich sind.
Ein Funktionsliteral kann einer Variablen zugewiesen oder direkt aufgerufen werden.
Calls
F
, ein Ausdruck f
von Funktionstyp Gegeben
f(a1, a2, … an)
Anrufe f
mit Argumenten a1, a2, … an
.
In einem Funktionsaufruf werden der Funktionswert und die Argumente in der üblichen Reihenfolge ausgewertet. Nach der Auswertung werden die Parameter des Aufrufs als Wert an die Funktion übergeben und die aufgerufene Funktion beginnt mit der Ausführung . Die Rückgabe-Parameter der Funktion werden mit dem Wert an die aufrufende Funktion zurückgegeben, wenn die Funktion zurückkehrt.
Defer statements
A "defer
" Anweisung ruft eine Funktion, deren Ausführung bis zu dem Moment aufgeschoben wird, um die umgebende Funktion zurückkehrt.
DeferStmt = "defer" Expression .
Der Ausdruck muss ein Funktions- oder Methodenaufruf sein. Jedes Mal, wenn die Anweisung "defer
" ausgeführt wird, werden der Funktionswert und die Parameter für den Aufruf wie üblich ausgewertet und erneut gespeichert, aber die aktuelle Funktion wird nicht aufgerufen.Stattdessen werden zurückgestellte Aufrufe in der LIFO-Reihenfolge ausgeführt, unmittelbar bevor die Umgebungsfunktion zurückkehrt, nachdem die zurückgegebenen Werte , falls vorhanden, ausgewertet wurden, bevor sie jedoch an den Aufrufer zurückgegeben werden.
Da Sie immer noch verwirrt sind, hier ein weiterer Versuch, eine Antwort auf Ihre Frage zu geben.
Im Kontext Ihrer Frage ist ()
der Funktionsaufruf-Operator.
Zum Beispiel die Funktionsliteral
func(i int) int { return 42 * i }
stellt eine anonyme Funktion.
Die Funktionsliteral durch die
func(i int) int { return 42 * i }(7)
eine anonyme Funktion repräsentiert
Operator
()
Funktionsaufruf folgt, die dann direkt aufgerufen wird.
Normalerweise werden in einem Funktionsaufruf der Funktionswert und die Argumente in der üblichen Reihenfolge ausgewertet. Nach der Auswertung werden die Parameter des Aufrufs als Wert an die Funktion übergeben und die aufgerufene Funktion beginnt mit der Ausführung. Die Rückgabeparameter der Funktion werden bei Rückgabe der Funktion durch Wert an die aufrufende Funktion zurückgegeben.
Das Aufrufen der Funktion durch die Defer-Anweisung ist jedoch ein Sonderfall. Jedes Mal, wenn die "Defer" -Anweisung ausgeführt wird, werden der Funktionswert und die Parameter für den Aufruf wie üblich ausgewertet und erneut gespeichert, aber die eigentliche Funktion wird nicht aufgerufen. Stattdessen werden verzögerte Aufrufe in LIFO-Reihenfolge ausgeführt, unmittelbar bevor die umgebende Funktion zurückkehrt, nachdem die Rückgabewerte, falls vorhanden, ausgewertet wurden, aber bevor sie an den Aufrufer zurückgegeben werden.
Der Ausdruck der Defer-Anweisung muss ein Funktions- oder Methodenaufruf sein, der direkt aufgerufen wird, nicht nur ein Funktions- oder Methodenliteral, das nicht direkt aufgerufen wird. Daher muss dem Funktions- oder Methodenliteral der Funktionsaufrufoperator ()
folgen, damit der Ausdruck der Defer-Anweisung ein Funktions- oder Methodenaufruf ist.
Die Zurückstellungs Anweisung
defer func(i int) int { return 42 * i }(7)
gültig ist.
Die Zurückstellungs Anweisung
defer func(i int) int { return 42 * i }
ist ungültig: syntax error: argument to go/defer must be function call
.
bekam ich Ihren Punkt, so in 'func (ch chan int) {ch <- ACK} (replyChan)', 'func (ch chan int) {ch <- ACK}' bedeutet die Definition der Schließung, '(replyChan) 'bedeutet" führe diese Schließung mit dem Parameter 'replyChan'" aus. –
Noch eine Frage zu Ihrem letzten Beispiel: Was ist der Unterschied zwischen 'in dem Moment, in dem die Schließung durchgeführt wird 'und' in dem Moment, als die Defer-Anweisung ausgeführt wurde? Wenn ich nach 'for {}' '' return '' habe, sollten beide 2 'Defer's gleichzeitig vor' return' ausgeführt werden, oder? –
@ReckHou: Run http://play.golang.org/p/Orm-0EaBY6 und schauen Sie sich die Ausgabe – zzzz