对于下面的代码段(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
?
答案 0 :(得分:3)
结果u.DummyHandler
是方法值,编译器通过创建函数闭包和修改函数名来实现方法。引用Ian here:
顺便说一下,这似乎已成为-fm。
您的代码正在获取方法值。 p.beHappy是beHappy的方法 绑定到p的特定值。这是通过创建一个 函数闭包,该闭包的代码需要一个名称。该 编译器碰巧通过在末尾粘贴fm来制作该名称,但它 可以是任何不会与任何其他函数名称冲突的东西。 在Go中没有任何方法可以命名该函数,因此名称是 与调试器以外的任何其他内容无关,或者如您所见, FuncForPC。
获取方法名称似乎更好的方法是直接引用该方法,如下所示:
func main() {
funcName((User).DummyHandler)
}
这将输出main.User.DummyHandler
。