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
}
Share:
16,025

Related videos on Youtube

user1175801
Author by

user1175801

Skämtfysiker

Updated on July 03, 2022

Comments

  • user1175801
    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
      Denys Séguret about 12 years
      It seems to me that the type of main is function. What would you expect as a name ?
  • Sonia
    Sonia about 12 years
    Or, without reflect, pc, _, _, _ := runtime.Caller(0) fmt.Println("Name of function: " + runtime.FuncForPC(pc).Name())
  • Denys Séguret
    Denys Séguret about 12 years
    Interesting. But I was assuming OP was looking for a more general solution, with any function.
  • Gwyneth Llewelyn
    Gwyneth Llewelyn almost 7 years
    Personally, 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
    Gwyneth Llewelyn almost 7 years
    The 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 stringsand filepathas well for your solution to work!
  • Rohanthewiz
    Rohanthewiz over 2 years
    Great 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!