获取调用函数的名称和包

时间:2018-10-26 16:08:11

标签: go

我需要知道go-package的名称和调用函数的函数(包括接收方名称)。

这是我当前的代码:

func retrieveCallInfo() {
    pc, _, _, _ := runtime.Caller(1)

    funcName := runtime.FuncForPC(pc).Name()
    lastDot := strings.LastIndexByte(funcName, '.')

    fmt.Printf("  Package: %s\n", funcName[:lastDot])
    fmt.Printf("  Func:   %s\n", funcName[lastDot+1:])
}

但是,代码的行为并不完全正确。

// When called from a conventional (free) function:
runtime.FuncForPC(pc).Name() // returns <package-path>.<funcName>

// When called from a method receiver function:
runtime.FuncForPC(pc).Name() // returns <package-path>.<receiverName>.<funcName>

从接收方函数调用时,接收方名称是程序包名称的一部分,而不是函数名称-这不是我想要的。

这是一个演示:https://play.golang.org/p/-99sZXr4ptD

在第二个示例中,我希望包名称为main,函数名称为empty.f。 由于点也是包名称的有效部分,因此我不能简单地在另一个点处拆分-也许实际上不是接收者,而是包名称的一部分。

因此,runtime.FuncForPC()返回的信息是模棱两可的,还不够。

如何获得正确的结果?

1 个答案:

答案 0 :(得分:1)

结果正确。您需要进行一些解析,才能以所需的方式格式化结果。例如,请尝试在字符串中最后一个斜杠之后的点上进行拆分:

pc, _, _, _ := runtime.Caller(1)
funcName := runtime.FuncForPC(pc).Name()
lastSlash := strings.LastIndexByte(funcName, '/')
if lastSlash < 0 {
    lastSlash = 0
}
lastDot := strings.LastIndexByte(funcName[lastSlash:], '.') + lastSlash

fmt.Printf("Package: %s\n", funcName[:lastDot])
fmt.Printf("Func:   %s\n", funcName[lastDot+1:])

游乐场:https://play.golang.org/p/-Nbos0a1Ifp