英文:
Why is there a "-fm" suffix when getting a function's name in Go?
问题
以下是翻译好的内容:
对于下面的代码片段(可以通过Go Playground运行):
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
?
英文:
For the snippet below (runnable via the Go Playground),
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)
}
The output is main.(User).DummyHandler-fm
.
Why is there a -fm
at the end of the function name?
答案1
得分: 13
原来u.DummyHandler
是一个方法值,编译器通过创建一个函数闭包并修改函数名来实现方法。引用Ian在这里的话:
> 顺便说一下,这似乎在最新版本中变成了-fm。
> 你的代码得到了一个方法值。p.beHappy是绑定到特定值p的beHappy方法。这是通过创建一个函数闭包来实现的,闭包的代码需要一个名称。编译器恰好在末尾加上了fm作为名称,但它可以是任何不会与其他函数名冲突的东西。在Go中没有办法给这个函数命名,所以这个名称对于除了调试器或者像你看到的FuncForPC之外的任何其他事情都是无关紧要的。
似乎更好的获取方法名称的方法是直接引用该方法,像这样:
func main() {
funcName((User).DummyHandler)
}
这将输出main.User.DummyHandler
。
英文:
Turns out u.DummyHandler
is a method value and the compiler implements methods by creating a function closure and modifying the function name. To quote Ian here:
> This seems to have become -fm on tip, by the way.
> Your code is getting a method value. p.beHappy is the beHappy method
bound to the specific value of p. That is implemented by creating a
function closure, and the code for that closure needs a name. The
compiler happens to make that name by sticking fm on the end, but it
could be anything that won't conflict with any other function name.
There isn't any way to name that function in Go, so the name is
irrelevant for anything other than the debugger or, as you see,
FuncForPC.
It seems like a better way to get a method's name is to reference the method directly, like so:
func main() {
funcName((User).DummyHandler)
}
This will output main.User.DummyHandler
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论