Go Type pour l'appel de fonction
Lors de l'utilisation de mots-clés tels que go et defer, les appels de fonction sont requis comme paramètres. Cependant, existe-t-il un type spécifique qui peut être utilisé de la même manière, en particulier pour créer une fonction qui attend un appel de fonction (pas simplement une fonction elle-même) comme argument ?
Limitations et solutions de contournement
Go ne fournit pas de type permettant directement cette fonctionnalité. Au lieu de cela, on peut utiliser des variables ou des valeurs typées fonction et les appeler plus tard comme s'il s'agissait de fonctions. Par exemple :
<code class="go">func myFunc() { fmt.Println("hi") } func main() { var f func() f = myFunc f() // This calls the function value stored in f: myFunc in this example }</code>
Pour obtenir la fonctionnalité souhaitée mentionnée dans le commentaire, enveloppez l'appel de fonction et les arguments dans un func() et utilisez-le. Par exemple :
<code class="go">func launch(f func()) { fmt.Println("Before launch") go func() { defer fmt.Println("After completion") f() }() }</code>
Utilisation :
<code class="go">func main() { launch(func() { fmt.Println("Hello, playground") }) time.Sleep(time.Second) }</code>
Sortie :
Before launch Hello, playground After completion
Cette méthode n'implique pas de solution de contournement directe. Si les paramètres changent, faites une copie avant d'appeler launch() et utilisez la copie dans le littéral de la fonction (fermeture).
Imiter l'enregistrement automatique des paramètres
Pour une fonction spécifique tapez, créez une fonction d’assistance avec une signature identique, renvoyant une fonction sans paramètres. La fonction renvoyée agit comme une fermeture, appelant la fonction d'origine avec les paramètres. L'appel de la fonction d'assistance enregistre efficacement les paramètres, imitant le comportement de defer :
<code class="go">func wrapPrintln(s string) func() { return func() { fmt.Println(s) } }</code>
Utilisation :
<code class="go">launch(wrapPrintln(s))</code>
Utilisation de Reflection
Reflection peut éliminer le besoin de copies manuelles, mais cette approche implique de transmettre des fonctions en tant que paramètres au lieu de les appeler. Il est également plus lent en raison de la surcharge de réflexion.
<code class="go">func launch(f interface{}, params ...interface{}) { fmt.Println("Before launch") go func() { defer fmt.Println("After completion") pv := make([]reflect.Value, len(params)) for i, v := range params { pv[i] = reflect.ValueOf(v) } reflect.ValueOf(f).Call(pv) }() }</code>
Exemple d'utilisation :
<code class="go">func main() { i, s := 1, "Hello, playground" launch(fmt.Printf, "%d %q\n", i, s) i, s = 2, "changed" time.Sleep(time.Second) }</code>
Sortie :
Before launch 1 "Hello, playground" After completion
Exception : valeur de la méthode
Une exception où la sauvegarde automatique des paramètres peut être utilisée concerne les valeurs de méthode. Lorsque x a un type statique T et que l'ensemble de méthodes de T contient la méthode M, x.M (sans l'appeler) représente une valeur de méthode qui capture une copie de x en tant que récepteur lorsque le résultat de l'expression (une valeur de fonction) est appelé.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!