Get name of function using reflection
16,025
Solution 1
The solution is to use FuncForPc which returns a *Func
.
This returns "main.main"
:
package main
import "fmt"
import "reflect"
import "runtime"
func main() {
name := runtime.FuncForPC(reflect.ValueOf(main).Pointer()).Name()
fmt.Println("Name of function : " + name)
}
If you want "main"
, just tokenize it.
Solution 2
package main
import "fmt"
import "runtime"
func main() {
pc, _, _, _ := runtime.Caller(0)
fmt.Println("Name of function: " + runtime.FuncForPC(pc).Name())
fmt.Println()
// or, define a function for it
fmt.Println("Name of function: " + funcName())
x()
}
func funcName() string {
pc, _, _, _ := runtime.Caller(1)
return runtime.FuncForPC(pc).Name()
}
func x() {
fmt.Println("Name of function: " + funcName())
y()
}
func y() {
fmt.Println("Name of function: " + funcName())
z()
}
func z() {
fmt.Println("Name of function: " + funcName())
}
Output:
Name of function: main.main
Name of function: main.main
Name of function: main.x
Name of function: main.y
Name of function: main.z
Solution 3
import runtime
func funcName() string {
pc, _, _, _ := runtime.Caller(1)
nameFull := runtime.FuncForPC(pc).Name() // main.foo
nameEnd := filepath.Ext(nameFull) // .foo
name := strings.TrimPrefix(nameEnd, ".") // foo
return name
}
Related videos on Youtube
Comments
-
user1175801 almost 2 years
I'm trying to use Go's reflection system to retrieve the name of a function but I get an empty string when calling the Name method on its type. Is this the expected behavior?
This is a simple example of how I approach the problem:
package main import "fmt" import "reflect" func main() { typ := reflect.TypeOf(main) name := typ.Name() fmt.Println("Name of function" + name) }
-
Denys Séguret about 12 yearsIt seems to me that the type of main is
function
. What would you expect as a name ?
-
-
Sonia about 12 yearsOr, without reflect, pc, _, _, _ := runtime.Caller(0) fmt.Println("Name of function: " + runtime.FuncForPC(pc).Name())
-
Denys Séguret about 12 yearsInteresting. But I was assuming OP was looking for a more general solution, with any function.
-
Gwyneth Llewelyn almost 7 yearsPersonally, I prefer your solution (or @Koala3's extension on your own solution), mostly because it allows to encapsulate the runtime calls inside a function which can then be 'safely' deployed elsewhere; if the Go runtime functions for some reason change, then the whole code needs to be changed at just one spot. Also, avoiding reflection is a neat trick, well done! :)
-
Gwyneth Llewelyn almost 7 yearsThe advantage of keeping the package name with the function name is, of course, that it's possible to have several functions with the same name in different packages... and then you have no idea which is which :) In fact, the main reason for me to search for this answer on SO was because I was unsure which of my functions was causing an error, and I needed to track down the precise package name besides the function name... Note that you need to import
strings
andfilepath
as well for your solution to work! -
Rohanthewiz over 2 yearsGreat answer Sonia! One caution is that
FuncForPC(pc)
returns a pointer, so you should check for nil always. I will share as an answer a full production-level utility function based on the core principles above. Thanks!