4

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

Zanecola
  • 1,394
  • 3
  • 15
  • 27
  • 4
    Related / possible duplicate: [Function Wrapper in GO](https://stackoverflow.com/questions/48827331/function-wrapper-in-go/48827861#48827861); and [Is there idiomatic scoped semantics in golang?](https://stackoverflow.com/questions/28170234/is-there-idiomatic-scoped-semantics-in-golang/28171214#28171214) – icza May 18 '21 at 11:25
  • 1
    I think the wrapper/decorator pattern in go is constrained by the function parameter and return type. – Zanecola May 18 '21 at 11:41

2 Answers2

3

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

f0xdx
  • 1,379
  • 15
  • 20
2

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.

Volker
  • 40,468
  • 7
  • 81
  • 87