有时候在Go的函数调用的过程中,我们需要知道函数被谁调用,比如打印日志信息等。例如下面的函数,我们希望在日志中打印出调用者的名字。你可以通过runtime.Caller、runtime.Callers、runtime.FuncForPC等函数更详细的跟踪函数的调用堆栈。
- Caller获取调用函数信息 参数作用:0表示调用函数本身
- Callers 获取程序计算器,第二个参数会返回程序计算器列表,return值是个数
- CallersFrames 获取栈的全部信息,通过和Callers配合来使用
- FuncForPC 通过reflect的ValueOf().Pointer作为入参,获取函数地址、文件行、函数名等信息
- Stack 获取栈信息
func main() {
Foo()
}
func Foo() {
fmt.Printf("我是 %s, %s 在调用我!\n", printMyName(), printCallerName())
Bar()
}
func Bar() {
fmt.Printf("我是 %s, %s 又在调用我!\n", printMyName(), printCallerName())
}
func printMyName() string {
pc, _, _, _ := runtime.Caller(1)
return runtime.FuncForPC(pc).Name()
}
func printCallerName() string {
pc, _, _, _ := runtime.Caller(2)
return runtime.FuncForPC(pc).Name()
}
func Caller(skip int) (pc uintptr, file string, line int, ok bool)
Caller可以返回函数调用栈的某一层的程序计数器、文件信息、行号。
0 代表当前函数,也是调用runtime.Caller的函数。1 代表上一层调用者,以此类推。
func Callers(skip int, pc []uintptr) int
Callers用来返回调用站的程序计数器, 放到一个uintptr中。
0 代表 Callers 本身,这和上面的Caller的参数的意义不一样,历史原因造成的。 1 才对应这上面的 0。
比如在上面的例子中增加一个trace函数,被函数Bar调用。
func Bar() {
fmt.Printf("我是 %s, %s 又在调用我!\n", printMyName(), printCallerName())
trace()
}
func trace() {
pc := make([]uin

本文介绍Go语言中如何使用反射和调用栈来获取函数调用信息及对象属性。通过runtime包中的函数,如Caller和FuncForPC,可以追踪函数调用堆栈;利用反射则能获取对象的类型属性并动态调用方法。
最低0.47元/天 解锁文章
1004

被折叠的 条评论
为什么被折叠?



