2011-08-13 66 views
56

給定一個函數,是否有可能得到它的名字?你說:如何在Go中獲取函數的名稱?

func foo() { 
} 

func GetFunctionName(i interface{}) string { 
    // ... 
} 

func main() { 
    // Will print "name: foo" 
    fmt.Println("name:", GetFunctionName(foo)) 
} 

有人告訴我,runtime.FuncForPC會有所幫助,但我不明白如何使用它。

回答

95

對不起回答我自己的問題,但我發現了一個解決方案:

package main 

import (
    "fmt" 
    "reflect" 
    "runtime" 
) 

func foo() { 
} 

func GetFunctionName(i interface{}) string { 
    return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() 
} 

func main() { 
    // This will print "name: main.foo" 
    fmt.Println("name:", GetFunctionName(foo)) 
} 
+0

雖然這似乎工作,但可能需要一些照顧:.Pointer()的文檔聲明「如果v的Kind是Func,返回的指針是底層代碼指針,但不一定足以唯一標識一個函數。只有保證結果是零,當且僅當v是一個nil func值。「 – jochen

+0

@jochen「不是一個func」意味着它可能返回誤報(即不同函數的指針)? – themihai

+0

@themihai我不知道,我引用的句子是https://golang.org/pkg/reflect/#Value.Pointer上的所有文檔。但引用似乎表明,可以爲不同的功能獲得相同的指針,不是嗎?如果是這種情況,'GetFunctionName'可能會爲不同的函數返回相同的名稱? – jochen

5

不正是你想要的,因爲它使用「運行」程序包日誌文件名和行號,但這裏是我如何做到這一點在我的海塗常見轉到庫(http://tideland-cgl.googlecode.com/):

+0

這並沒有什麼幫助。我不需要獲取有關調用堆棧的信息,而是獲取有關給定函數的信息。我相信如果我知道如何獲得給定的函數引用(如果可能的話),相應的問題將得到解答。 – moraes