Pourquoi ajouter “()” après la fermeture du corps dans Golang?
Je suis en train de lire The Go Programming Language Specifications
et je me trouve pas vraiment comprendre avec les "()" après la fermeture du corps:
Dans Function literals
:
func(ch chan int) { ch <- ACK }(replyChan)`
Dans Defer statements
's exemple:
//f returns 1
func f() (result int) {
defer func() {
result++
}() //why and how?
return 0
}
Je ne suis pas clair sur la raison d'ajouter & utilisation de "()" après la fermeture du corps, de l'espoir, quelqu'un peut expliquer cela clairement.
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas que
()
doit être ajouté après (seulement) un fermeture dansdefer
. Le langage de spécifications pour le reporter la déclaration mandat que "l'Expression' toujours doit être un appel de fonction.Et pourquoi est-il si? C'est la même qu'avec toute autre fonction, de "différer" ou pas:
Considérer:
et
vs
La première expression du membre de droite est une fonction de la valeur. Dans la deuxième version, le membre de droite est la valeur retourné par la fonction - c'est à dire un appel de fonction.
Est donc la sémantique de:
vs
sauf que la première version n'a pas de sens dans le contexte de "différer", et donc le cahier des charges mentionne qu'il doit être le second formulaire (uniquement).
C'est à mon humble avis aussi plus facile à apprendre, grâce à l'orthogonalité avec le évoquées ci-dessus appel de fonction à l'extérieur de la "différer" instruction.
Notez également qu'un appel de fonction n'est pas uniquement fn-expr suivie par
()
, mais une expression de la liste est généralement à l'intérieur de la parenthèse (y compris une liste vide). Il y a une grosse différence entre:et
La première version imprime la valeur de " i "dans le moment de la fermeture exécute, la deuxième imprime la valeur de" i " dans le moment où le reporter déclaration était exécuté.
func(ch chan int) { ch <- ACK }(replyChan)
,func(ch chan int) { ch <- ACK }
signifie que la définition de la fermeture,(replyChan)
signifie "exécuter cette fermeture avec paramètrereplyChan
".in the moment when the closure executes
&in the moment when the defer statement was executed
? Si j'ai unreturn
aprèsfor{}
, à la fois de ces 2defer
s doit s'exécuter avantreturn
en même temps, n'est-ce pas?defer
exécution, savez-vous quel article peut expliquer cela?func(ch chan int) { ch <- ACK }(replyChan)
ch
etchan
sont les paramètres de la fonction littérale, si oui, pourquoi ne sont-ils pas séparés par une virgule? Merci?i
au point de le remettre (car la fermeture a uni
argument), tandis que la première forme de feuillesi
libre (pas d'arguments à la fermeture). La première forme imprime la valeuri
a en fonction de la fin.Puisque vous êtes encore confus, voici une autre tentative de fournir une réponse à votre question.
Dans le contexte de votre question,
()
est l'appel à la fonction d'opérateur.Par exemple, la fonction littérale
représente une fonction anonyme.
La fonction littérale suivie par la
()
l'invocation de la fonction de l'opérateurreprésente une fonction anonyme qui est ensuite directement invoquée.
Normalement, dans un appel de fonction, la valeur de la fonction et les arguments sont évalués dans l'ordre habituel. Après ils sont évalués, les paramètres de l'appel sont transmis par valeur de la fonction et de la fonction appelée commence l'exécution. Le retour des paramètres de la fonction sont passés par valeur de retour à l'appel de la fonction lorsque la fonction retourne.
Cependant, l'invocation de la fonction par le biais de la reporter l'instruction est un cas spécial. Chaque fois que le "reporter" exécution d'une instruction, la valeur de la fonction et les paramètres de l'appel sont évalués comme d'habitude et enregistré à nouveau, mais la fonction n'est pas appelée. Au lieu de cela, différé appels sont exécutés dans l'ordre LIFO immédiatement avant les environs de la fonction retourne, après les valeurs de retour, le cas échéant, ont été évalués, mais avant qu'ils sont retourné à l'appelant.
La reporter la déclaration de l'expression doit être une fonction ou un appel de méthode qui est appelée directement, et pas seulement une fonction ou une méthode littérale qui n'est pas appelé directement. Par conséquent, la fonction ou de la méthode littérale doit être suivie par le
()
l'invocation de la fonction de l'opérateur, de sorte que le reporter déclaration expression est une fonction ou un appel de méthode.Le reporter déclaration
est valide.
Le reporter déclaration
est pas valide:
syntax error: argument to go/defer must be function call
.Si vous ne voulez pas lire de longues réponses:
Est la même que: