英文:
How to get the current function name
问题
为了追踪目的,我想要打印出当前函数的名称,就像gcc中的__FUNCTION__
宏一样。
这样当我有一个函数:
func foo() {
trace()
}
它会自动打印出Entering foo()...
或类似的内容。
英文:
For tracing purpose, I'd like to print out current function name, like the __FUNCTION__
macro in gcc.
So that when I have a function
func foo () {
trace()
}
it will automatically print out Entering foo()...
or something like that.
答案1
得分: 71
[注意:Go 1.7+建议使用runtime.CallersFrames
而不是runtime.FuncForPC
;另一个答案有一个更新的示例。]
在这里,runtime
包是你的朋友:
func trace() {
pc := make([]uintptr, 10) // 至少需要1个条目
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
file, line := f.FileLine(pc[0])
fmt.Printf("%s:%d %s\n", file, line, f.Name())
}
英文:
[Note: Go 1.7+ recommends using runtime.CallersFrames
instead of runtime.FuncForPC
; another answer has an updated example].
Package runtime is your friend here:
func trace() {
pc := make([]uintptr, 10) // at least 1 entry needed
runtime.Callers(2, pc)
f := runtime.FuncForPC(pc[0])
file, line := f.FileLine(pc[0])
fmt.Printf("%s:%d %s\n", file, line, f.Name())
}
答案2
得分: 52
Go 1.7增加了一些运行时函数来改进访问堆栈帧信息。
从Go 1.7发布说明中可以看到:
新的函数CallersFrames将从Callers获取的PC切片转换为与调用堆栈对应的帧序列。与直接使用FuncForPC相比,应优先使用这个新的API,因为帧序列可以更准确地描述内联函数调用的调用堆栈。
改进后的示例代码:
func trace2() {
pc := make([]uintptr, 15)
n := runtime.Callers(2, pc)
frames := runtime.CallersFrames(pc[:n])
frame, _ := frames.Next()
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
}
Playground: https://play.golang.org/p/YkEN5mmbRld
英文:
Go 1.7 added some runtime functions to improve accessing stack frame information.
From the Go 1.7 Release Notes:
> The new function CallersFrames translates a PC slice obtained from Callers into a sequence of frames corresponding to the call stack. This new API should be preferred instead of direct use of FuncForPC, because the frame sequence can more accurately describe call stacks with inlined function calls.
An improved example:
func trace2() {
pc := make([]uintptr, 15)
n := runtime.Callers(2, pc)
frames := runtime.CallersFrames(pc[:n])
frame, _ := frames.Next()
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
}
Playground: https://play.golang.org/p/YkEN5mmbRld
答案3
得分: 10
以下是一个不需要分配数组的简化版本。
func trace() (string, int, string) {
pc, file, line, ok := runtime.Caller(1)
if !ok { return "?", 0, "?" }
fn := runtime.FuncForPC(pc)
if fn == nil { return file, line, "?" }
return file, line, fn.Name()
}
这个函数用于获取调用它的函数的文件名、行号和函数名。
英文:
Here's a simpler version that doesn't need to allocate an array.
func trace() (string, int, string) {
pc, file, line, ok := runtime.Caller(1)
if !ok { return "?", 0, "?" }
fn := runtime.FuncForPC(pc)
if fn == nil { return file, line, "?" }
return file, line, fn.Name()
}
答案4
得分: 2
pc, _, _, _ := runtime.Caller(0)
log.Println(runtime.FuncForPC(pc).Name())
翻译结果:
pc, _, _, _ := runtime.Caller(0)
log.Println(runtime.FuncForPC(pc).Name())
英文:
pc, _, _, _ := runtime. Caller(0)
log.Println(runtime.FuncForPC(pc).Name())
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论