Home > Backend Development > Golang > How to Create a Function Wrapper in Go to Inject Code Before and After Execution?

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

DDD
Release: 2024-12-03 00:56:11
Original
233 people have browsed it

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

Function Wrapper in Go

Question:

How can I create a function wrapper in Go to inject code before and after a function execution?

Answer:

In Go, it's possible to create a function wrapper that takes a function as an argument and returns a new function value. This allows for injecting code before and after the call to the wrapped function.

Here's an example of a wrapper function:

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

Wrapped Function with Signature:

If you know the signature of the function to be wrapped, you can create a wrapper function that takes a function value of that type and returns another function value of the same type. This is exemplified below:

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
    }
}
Copy after login

Supporting Multiple Function Types:

To support multiple function types, you can create separate wrapper functions for each distinct type:

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
    }
}
Copy after login

Generic Wrapper Using Reflection:

While Go lacks generics, a more generic approach using reflection is 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
}
Copy after login

However, this approach uses an interface{} return type and requires type assertions when using it.

Example Usage:

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

Output:

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

The above is the detailed content of How to Create a Function Wrapper in Go to Inject Code Before and After Execution?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template