对于下面的代码片段(可通过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
是一个方法值,编译器通过创建函数闭包和修改函数名来实现方法。引用Ian的话:
获取方法名称的更好方法似乎是直接引用该方法,如下所示:顺便说一下,这似乎变成了tip上的-fm。
你的代码正在获取一个方法值。beHappy是beHappy方法绑定到p的特定值,这是通过创建a来实现的函数闭包,该闭包的代码需要一个名称。的编译器通过在末尾加上FM来生成这个名字,但是它可以是任何不会与任何其他函数名冲突的名称。在Go中没有办法命名这个函数,所以它的名字是与除调试器之外的任何东西都无关,或者,如您所见,FuncForPC .
func main() {
funcName((User).DummyHandler)
}
这将输出main.User.DummyHandler