Golang Go语言中程序怎么在运行时得到包名

需求是获取调用栈的包名、函数名。
目前利用 runtime.Callers 和 runtime.CallersFrames ,得到的函数名格式为:<packageName>.<functionName>。比如:github.com/user/project.function
但是……
github.com 支持仓库名带符号"."。
函数内嵌套的函数,和结构体方法的名称,也带符号"."。
那么可能得到下面的完整函数名:
github.com/user/my.project.mystruct.method
现在要做的,就是提取出其中的包名,和不带包名的函数名。
Golang Go语言中程序怎么在运行时得到包名


更多关于Golang Go语言中程序怎么在运行时得到包名的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

runtime 肯定没问题,不过不是只有这个啊

别忘记还有一个 runtime/debug.ReadBuildInfo

更多关于Golang Go语言中程序怎么在运行时得到包名的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


‘/’ 只会出现在包名里,先用’/'分割,然后最后一个元素是 包名 + ‘.’ + 函数名,再用 ‘.’ 分割最后一个元素,然后把包名拼起来就行了。

import (
“runtime”
“strings”
)

func GetCallerPackage() string {
pc, _, _, ok := runtime.Caller(1)
if ok {
name := runtime.FuncForPC(pc).Name()
slashIndex := strings.LastIndexByte(name, ‘/’) + 1

pointIndex := strings.IndexByte(name[slashIndex:], ‘.’)

return name[:slashIndex+pointIndex]
}

return “<unknown>”
}

额。。。。这不是常量吗?自己引用了什么包是确定的,可以直接写死

在Go语言中,程序在运行时获取当前包名并不是直接支持的功能,因为Go语言的运行时反射机制(reflect包)主要关注于类型、值和方法,而不直接提供包名的信息。然而,你可以通过一些间接的方法来实现类似的功能。

一种常见的方法是使用构建标签(build tags)和构建时生成的代码。你可以在构建过程中通过自定义脚本或工具生成一个包含包名信息的Go源文件,然后在运行时通过导入该文件来获取包名。

另一种方法是利用Go的debug/pedebug/elf等包(取决于你的操作系统)来分析编译后的二进制文件,但这通常非常复杂且不推荐用于生产环境,因为它依赖于二进制文件的内部结构和实现细节,这些在不同版本的Go编译器中可能会发生变化。

对于大多数应用场景,建议重新考虑是否真的需要在运行时获取包名。通常,包名在编译时就已经确定,并且主要用于代码的组织和命名空间分隔。如果需要在运行时传递或引用包相关的信息,可以考虑使用显式的配置或常量来替代。

总之,虽然Go语言没有直接提供在运行时获取包名的功能,但你可以通过构建时生成代码或分析二进制文件等间接方法来实现类似效果,不过这些方法都有其局限性和复杂性。

回到顶部