2015-10-03 54 views
3

對於下面的代碼段(runnable via the Go Playground在Go中獲取函數名稱時爲什麼會有「-fm」後綴?

package main 

import (
    "fmt" 
    "net/http" 
    "reflect" 
    "runtime" 
) 

type User struct{} 

var u = &User{} 

func (_ User) DummyHandler(w http.ResponseWriter, r *http.Request) {} 

func funcName(i interface{}) { 
    p := reflect.ValueOf(i).Pointer() 
    n := runtime.FuncForPC(p).Name() 
    fmt.Println(n) 
} 

func main() { 
    funcName(u.DummyHandler) 
} 

輸出爲main.(User).DummyHandler-fm

爲什麼函數名稱末尾有-fm

回答

3

原來u.DummyHandler是一個方法值,編譯器通過創建函數閉包和修改函數名來實現方法。引用Ian here

順便說一下,這似乎已成爲-fm提示。

您的代碼正在獲取方法值。 p.beHappy是beHappy方法 綁定到p的具體值。這是通過創建一個 函數閉包來實現的,並且該閉包的代碼需要一個名稱。 編譯器恰好通過在最後加上fm來創建該名稱,但它可能是任何不會與任何其他函數名稱衝突的東西。 在Go中沒有任何方法來命名該函數,因此名稱爲 與除調試器之外的任何內容無關,或者如您所見, FuncForPC。

這似乎是一個更好的方式來獲得一個方法的名稱是直接引用的方法,像這樣:

func main() { 
    funcName((User).DummyHandler) 
} 

這將輸出main.User.DummyHandler

相關問題