为什么在 Go 中获取函数名时会有“-fm”后缀?
Why is there a "-fm" suffix when getting a function's name in Go?
对于下面的代码段 (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
是一个方法值,编译器通过创建函数闭包和修改函数名来实现方法。引用 Ian 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
.
对于下面的代码段 (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
是一个方法值,编译器通过创建函数闭包和修改函数名来实现方法。引用 Ian 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
.