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
Libérer: 2024-10-29 03:29:02
original
907 Les gens l'ont consulté

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>
Copier après la connexion

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>
Copier après la connexion

Utilisation :

<code class="go">func main() {
    launch(func() {
        fmt.Println("Hello, playground")
    })

    time.Sleep(time.Second)
}</code>
Copier après la connexion

Sortie :

Before launch
Hello, playground
After completion
Copier après la connexion

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>
Copier après la connexion

Utilisation :

<code class="go">launch(wrapPrintln(s))</code>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

Sortie :

Before launch
1 "Hello, playground"
After completion
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal