Is there a way to intercept go function?

Viewed 536

I'm new to golang and want to know if there is any way to intercept a function.

For example, if I have:

func (foo Foo) f1(a int) int {...}
func (foo Foo) f2(a, b int) int {...}
func (foo Foo) f3(a, b, c int) int {...}

and I want to implement some logging function, instead of putting pre and post interceptor in each function:

func (foo Foo) f1(a int) int {
  preCall()
  ...
  postCall()
}

func (foo Foo) f2(a, b int) int {
  preCall()
  ...
  postCall()
}

func (foo Foo) f3(a, b, c int) int {
  preCall()
  ...
  postCall()
}

Is there a better pattern to do this in go? Such as AOP in Java.

Thanks

2 Answers

As @Volker has pointed out, there is no way to intercept / weave code in the AOP sense. You can, however, work around the function parameter limitation with the decorator pattern by using closures

package main

import "fmt"

type Foo struct{}

func (foo Foo) f1(a int) {
    fmt.Printf("f1: %v\n", a)
}

func (foo Foo) f2(a, b int) {
    fmt.Printf("f2: %v, %v\n", a, b)
}

func (foo Foo) f3(a, b, c int) int {
    fmt.Printf("f3: %v, %v, %v\n", a, b, c)
    return a + b + c
}

func Wrap(f func()) {
    fmt.Printf("preCall\n")
    f()
    fmt.Printf("postCall\n")
}

func main() {
    f := Foo{}

    var res int
    Wrap(func() { f.f1(1) })
    Wrap(func() { f.f2(1, 2) })
    Wrap(func() { res = f.f3(1, 2, 3) })

    fmt.Printf("res of f3: %v\n", res)
}

Go Playgorund

Is there a way to intercept go function?

No, there isn't.

Go doesn't provide such things as the source is compiled directly to machine code and the runtime of Go has no option to hook in such things.

Related