Maison >développement back-end >Golang >Go peut-il représenter directement les appels de fonction sous forme de type à utiliser comme paramètres ?

Go peut-il représenter directement les appels de fonction sous forme de type à utiliser comme paramètres ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-29 03:29:02917parcourir

Can Go directly represent function calls as a type for use as parameters?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn