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

16

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

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

package main

import "fmt"
import "reflect"

func main() {
    typ := reflect.TypeOf(main)
    name := typ.Name()
    fmt.Println("Name of function" + name)
}
Это очень важно. Пример кода, вероятно, не должен работать, но я думаю, что название вопроса является действительным. Laserallan
Мне кажется, что тип основногоfunction, Что бы вы ожидали в качестве имени? Denys Séguret

Ваш Ответ

3   ответа
28
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())
}

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

Лично я предпочитаю ваше решение (или расширение @ Koala3 для вашего собственного решения), главным образом потому, что оно позволяет инкапсулировать вызовы времени выполнения внутри функции, которая затем может быть «безопасно». развернут в другом месте; если по какой-либо причине функции времени выполнения Go меняются, то весь код необходимо изменить в одном месте. Кроме того, избегать размышлений - это отличный трюк, хорошо сделанный! :)
22

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"Обозначь это.

Интересно. Но я предполагал, что OP ищет более общее решение с любой функцией.
Благодарю. Это решило проблему! Laserallan
Или без отражения pc, _, _, _: = runtime.Caller (0) fmt.Println (& quot; имя функции: & quot; + runtime.FuncForPC (pc) .Name ())
2
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
}
Преимущество сохранения имени пакета вместе с именем функции состоит в том, что, конечно, можно иметь несколько функций с одним и тем же именем в разных пакетах ... и тогда вы даже не представляете, что есть что. На самом деле, Основная причина поиска этого ответа в SO была в том, что я не был уверен, какая из моих функций вызывала ошибку, и мне нужно было отследить точное имя пакета, кроме имени функции ... Обратите внимание, что вам нужно импортироватьstringsа такжеfilepathа также чтобы ваше решение работало!

Похожие вопросы