Maison >développement back-end >Golang >Comment créer un wrapper de fonction dans Go to Inject Code avant et après l'exécution ?

Comment créer un wrapper de fonction dans Go to Inject Code avant et après l'exécution ?

DDD
DDDoriginal
2024-12-03 00:56:11293parcourir

How to Create a Function Wrapper in Go to Inject Code Before and After Execution?

Wrapper de fonction dans Go

Question :

Comment puis-je créer un wrapper de fonction dans Aller injecter du code avant et après une fonction exécution ?

Réponse :

Dans Go, il est possible de créer un wrapper de fonction qui prend une fonction comme argument et renvoie une nouvelle valeur de fonction. Cela permet d'injecter du code avant et après l'appel à la fonction enveloppée.

Voici un exemple de fonction wrapper :

func funcWrapper(myFunc interface{}) {
    fmt.Println("Before")
    // Call myFunc
    fmt.Println("After")
}

Fonction enveloppée avec signature :

Si vous connaissez la signature de la fonction à envelopper, vous pouvez créer une fonction wrapper qui prend une valeur de fonction de ce type et renvoie une autre valeur de fonction du même type. Ceci est illustré ci-dessous :

func wrap(f func(i int) int) func(i int) int {
    return func(i int) (ret int) {
        fmt.Println("Before, i =", i)
        ret = f(i)
        fmt.Println("After, ret =", ret)
        return
    }
}

Prise en charge de plusieurs types de fonctions :

Pour prendre en charge plusieurs types de fonctions, vous pouvez créer des fonctions wrapper distinctes pour chaque type distinct :

func wrap(f func()) func() {
    return func() {
        fmt.Println("Before func()")
        f()
        fmt.Println("After func()")
    }
}

func wrapInt2Int(f func(i int) int) func(i int) int {
    return func(i int) (ret int) {
        fmt.Println("Before func(i int) (ret int), i =", i)
        ret = f(i)
        fmt.Println("After func(i int) (ret int), ret =", ret)
        return
    }
}

Wrapper générique utilisant Réflexion :

Bien que Go manque de génériques, une approche plus générique utilisant la réflexion est possible :

func wrap(f interface{}) interface{} {
    switch f2 := f.(type) {
    case func(i int) (ret int):
        return func(i int) (ret int) {
            fmt.Println("Before func(i int) (ret int), i =", i)
            ret = f2(i)
            fmt.Println("After func(i int) (ret int), ret =", ret)
            return
        }
    case func():
        return func() {
            fmt.Println("Before func()")
            f2()
            fmt.Println("After func()")
        }
    }
    return nil
}

Cependant, cette approche utilise un type de retour interface{} et nécessite des assertions de type lorsque en l'utilisant.

Exemple Utilisation :

wf := wrap(myfunc).(func(int) int)
ret := wf(2)
fmt.Println("Returned:", ret)

Sortie :

Before, i = 2
myfunc called with 2
After, ret = 4
Returned: 4

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