我可以反省main.main包的名称吗?

时间:2012-02-17 18:43:55

标签: module go packages introspection

这是一个相当小的问题,但我目前正在尝试使用golang编写基于约定的设置存储库。如果我能以编程方式确定想要存储某些内容的运行包名称(例如"github.net/author/projectname/pkg")来调用我的库函数,那将是一个很棒的API。

使用Python,inspect模块可以实现类似的功能,甚至可以使用__main__.__file__来查看文件系统。

1 个答案:

答案 0 :(得分:4)

如果您使用以下功能,则可以获得类似的信息:

代码可能如下所示:

pc, file, line, ok := runtime.Caller(1)
if !ok { /*failed*/ }
println(pc, file, line, ok)

f := runtime.FuncForPC(pc)
if f == nil { /*failed*/ }
println(f.Name())

如果我将上面的代码(第一行更改为runtime.Caller(0))放入GOROOT中安装的(随机选择的)Go库中,则会打印出来:

134626026 /tmp/go-build223663414/github.com/mattn/go-gtk/gtk/_obj/gtk.cgo1.go -4585 true
github.com/mattn/go-gtk/gtk.Init

或打印:

134515752 /home/user/go/src/github.com/mattn/go-gtk/example/event/event.go 12 true
main.main

第1行和第2行的文件名似乎包含您要查找的信息。

有两个问题:

  • 如果编译器自动内联函数,则可能会给出错误的结果

  • 对于包F中定义的任何函数main,函数名称仅为main.F。例如,如果从runtime.Caller(0)调用main(),则即使在main.main中找到的Go文件中定义了main()函数,函数名也是GOROOT/src/github.com/mattn/go-gtk/...。在这种情况下,runtime.Caller的输出比runtime.FuncForPC的输出更有用。