How do I get the values of arguments passed inside a func() argument in GO?

huangapple go评论92阅读模式
英文:

How do I get the values of arguments passed inside a func() argument in GO?

问题

我正在尝试在路由中创建中间件,并想知道如何获取传递给func()参数的参数值。

例如:

func (c appContainer) Get(path string, fn func(rw http.ResponseWriter, req *http.Request)) {

    // 如何获取传递给fn func()的rw和req的值?

    c.providers[ROUTER].(Routable).Get(path, fn)
}

我查看了反射文档,但对我来说并不清楚,或者也许有更简单的方法?

编辑(解决方案)

事实证明,不需要使用反射,正如Adam在对我的问题的回答中建议的那样,以及Jason在他的golang-nuts回复中提到的那样。

思路是创建一个新的匿名函数,然后拦截传递给它的参数以进行修改/增强,然后再调用原始函数。

这就是我最终采取的方法,它非常有效,我在这里发布以帮助其他人:

type handlerFn func(rw http.ResponseWriter, req *http.Request)

func (c appContainer) Get(path string, fn handlerFn) {
    nfn := func(rw http.ResponseWriter, req *http.Request) {
        c.providers[LOGGER].(Loggable).Info("[%s] %s", req.Method, req.URL.Path)
        fn(rw, req)
    }
    c.providers[ROUTER].(Routable).Get(path, nfn)
}
英文:

I am trying to create middleware inside routes and wondering how one can get the values of arguments passed inside a func() argument.

For example:

func (c appContainer) Get(path string, fn func(rw http.ResponseWriter, req *http.Request)) {

    // HOW DO I GET THE VALUES OF rw AND req PASSED IN fn func()?

	c.providers[ROUTER].(Routable).Get(path, fn)
}

I looked through the reflection docs but it's not clear to me or perhaps there is a simpler way?

EDITED (SOLUTION)

It turns out reflection is not needed, as suggested by Adam in his response to this post, as well as Jason on his golang-nuts reply to my question.

The idea is to create a new anonymous function which then intercepts the parameters passed to it for modification/enhancement before calling the original function.

This is what I ended up doing and it worked like a charm, which I am posting in case it helps someone else:

type handlerFn func(rw http.ResponseWriter, req *http.Request)

func (c appContainer) Get(path string, fn handlerFn) {
	nfn := func(rw http.ResponseWriter, req *http.Request) {
		c.providers[LOGGER].(Loggable).Info("[%s] %s", req.Method, req.URL.Path)
		fn(rw, req)
	}
	c.providers[ROUTER].(Routable).Get(path, nfn)
}

答案1

得分: 3

简单回答:你不能在那个地方实现。至少不是在那个地方。

变量rwreq只有在调用函数fn时才有意义(或者调用fn的函数,该函数可能会有rwreq变量)。

在你的情况下,可能是在appContainer使用配置的路由的地方。

为了更好地理解中间件的概念,可以在这里找到一个简单的例子:https://golang.org/doc/articles/wiki/

你可能需要向下滚动到"Introducing Function Literals and Closures"部分。

英文:

simple answer: you don't. Not at that place at least

the variables rw and req make first sense if the function fn is called. (or a function that calls fn, which probably will have rw and req variables)

In your case it is probably where appContainer uses the routes configured

To better understand how middleware concept works a simple example can be found here: https://golang.org/doc/articles/wiki/

you might want to scroll down to "Introducing Function Literals and Closures"

huangapple
  • 本文由 发表于 2015年7月2日 11:43:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/31175233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定