Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there a "-fm" suffix when getting a function's name in Go?

Tags:

reflection

go

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?

like image 717
nucleartide Avatar asked Oct 03 '15 17:10

nucleartide


1 Answers

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.

like image 151
nucleartide Avatar answered Sep 21 '22 15:09

nucleartide