说一些非常简单的Golang代码:
package main
import "fmt"
func plus( a int, b int) int {
return a+b
}
func plusPlus(a,b,c int) int {
return a +b + c
}
func main() {
ptr := plus
ptr2 := plusPlus
fmt.Println(ptr)
fmt.Println(ptr2)
}
Run Code Online (Sandbox Code Playgroud)
这有以下输出:
0x2000
0x2020
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?这看起来不像是一个函数指针,或任何类型的指针,可以在堆栈中找到.我也理解Go,虽然在线程部门提供了一些不错的低级功能,但也需要一个操作系统才能运行; C可以在所有计算机平台上运行,操作系统可以写入其中,而Go需要操作系统才能运行,实际上现在只能在少数操作系统上运行.常规函数指针是否意味着它可以在VM上运行?或者编译器是否只链接到低级C函数?
hob*_*bbs 10
Go不在虚拟机上运行.这些是函数的实际地址.
在我的机器上(去1.4.1,Linux amd64)程序打印
0x400c00
0x400c20
Run Code Online (Sandbox Code Playgroud)
它们与您示例中的值不同,但仍然很低.检查已编译的代码:
$ nm test | grep 'T main.plus'
0000000000400c00 T main.plus
0000000000400c20 T main.plusPlus
Run Code Online (Sandbox Code Playgroud)
这些是函数的实际地址.func plus编译为仅19字节的代码,因此plusPlus稍后仅出现32(0x20)字节以满足最佳对齐要求.
为了好奇,这里是func plusfrom 的反汇编objdump -d,这应该消除Go编译为除本机代码之外的任何内容的任何疑问:
0000000000400c00 <main.plus>:
400c00: 48 8b 5c 24 08 mov 0x8(%rsp),%rbx
400c05: 48 8b 6c 24 10 mov 0x10(%rsp),%rbp
400c0a: 48 01 eb add %rbp,%rbx
400c0d: 48 89 5c 24 18 mov %rbx,0x18(%rsp)
400c12: c3 retq
Run Code Online (Sandbox Code Playgroud)
它们是函数值:
package main
import "fmt"
func plus(a int, b int) int {
return a + b
}
func plusPlus(a, b, c int) int {
return a + b + c
}
func main() {
funcp := plus
funcpp := plusPlus
fmt.Println(funcp)
fmt.Println(funcpp)
fmt.Println(funcp(1, 2))
fmt.Println(funcpp(1, 2, 3))
}
Run Code Online (Sandbox Code Playgroud)
输出:
0x20000
0x20020
3
6
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10856 次 |
| 最近记录: |