Получить имя функции, используя отражение в Голанге

Я пытаюсь использовать систему отражения Go, чтобы получить имя функции, но я получаю пустую строку при вызове метода Name по типу. Это ожидаемое поведение?

Это простой пример того, как я подхожу к проблеме:

package main

import "fmt"
import "reflect"

func main() {
    typ := reflect.TypeOf(main)
    name := typ.Name()
    fmt.Println("Name of function" + name)
}

Ответ 1

Решение заключается в использовании FuncForPc, который возвращает *Func.

Это возвращает "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)
}

Если вы хотите "main", просто отметьте его.

Ответ 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())
}

Вывод:

Название функции: main.main

Название функции: main.main
Название функции: main.x
Название функции: main.y
Название функции: main.z

Ответ 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
}