【问题标题】:Is there a way to intercept go function?有没有办法拦截 go 函数?
【发布时间】:2021-05-18 11:15:05
【问题描述】:

我是golang的新手,想知道有没有什么方法可以拦截一个函数。

例如,如果我有:

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

我想实现一些日志功能,而不是在每个函数中放置前置和后置拦截器:

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()
}

在 go 中有没有更好的模式来做到这一点?比如Java中的AOP。

谢谢

【问题讨论】:

标签: go


【解决方案1】:

正如@Volker 所指出的,没有办法在 AOP 意义上拦截/编织代码。但是,您可以通过使用闭包来解决装饰器模式的函数参数限制

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

【讨论】:

  • 但你永远无法收集返回值
【解决方案2】:

有没有办法拦截go函数?

不,没有。

Go 不提供源代码直接编译成机器码,Go 的运行时没有选项挂钩这些东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    相关资源
    最近更新 更多