For the snippet below (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)
}
The output is main.(User).DummyHandler-fm
.
Why is there a -fm
at the end of the function name?
Turns out u.DummyHandler
is a method value and the compiler implements methods by creating a function closure and modifying the function name. To quote 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.
It seems like a better way to get a method's name is to reference the method directly, like so:
func main() {
funcName((User).DummyHandler)
}
This will output main.User.DummyHandler
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With