对于下面的代码片段 ( runnable via the Go Playground ),
package main
import (
"fmt"
"net/http"
"reflect"
"runtime"
)
type User struct{}
var u = &User{}
func (_ User) DummyHandler(w http.ResponseWriter, r *http.Request) {}
func funcName(i interface{}) {
p := reflect.ValueOf(i).Pointer()
n := runtime.FuncForPC(p).Name()
fmt.Println(n)
}
func main() {
funcName(u.DummyHandler)
}
输出是 main.(User).DummyHandler-fm
。
为什么函数名后面有一个-fm
?
最佳答案
原来 u.DummyHandler
是一个方法值,编译器通过创建一个函数闭包并修改函数名来实现方法。引用伊恩 here :
This seems to have become -fm on tip, by the way.
Your code is getting a method value. p.beHappy is the beHappy method bound to the specific value of p. That is implemented by creating a function closure, and the code for that closure needs a name. The compiler happens to make that name by sticking fm on the end, but it could be anything that won't conflict with any other function name. There isn't any way to name that function in Go, so the name is irrelevant for anything other than the debugger or, as you see, FuncForPC.
获取方法名称的更好方法似乎是直接引用该方法,如下所示:
func main() {
funcName((User).DummyHandler)
}
这将输出 main.User.DummyHandler
。
关于reflection - 为什么在 Go 中获取函数名时会有 "-fm"后缀?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32925344/