Golang是否在虚拟机上运行?

时间:2015-07-08 00:05:35

标签: go

说一些非常简单的Golang代码:

django.utils.crypto

这有以下输出:

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)
}

这里发生了什么?这看起来不像是一个函数指针,或任何类型的指针,可以在堆栈中找到。我也理解Go,虽然在线程部门提供了一些不错的低级功能,但也需要一个操作系统才能运行; C可以在所有计算机平台上运行,操作系统可以写入其中,而Go需要操作系统才能运行,实际上现在只能在少数操作系统上运行。常规函数指针是否意味着它可以在VM上运行?或者编译器只链接到低级C函数?

3 个答案:

答案 0 :(得分:9)

Go无法在虚拟机上运行。

从语言规范的角度来看,ptrptr2function values。它们可以被称为ptr(1, 2)ptr2(1, 2, 3)

深入了解实现,变量ptrptr2是指向func值的指针。有关func值的信息,请参阅Function Call设计文档。注意语言的“函数”值和实现的“func”值之间的区别。

由于reflectionfmt使用indirects API通过func值来获取指针以进行打印,因此对fmt.Println(ptr)的调用会打印出实际的地址。 plus功能。

答案 1 :(得分:8)

Go不在虚拟机上运行。这些是函数的实际地址。

在我的机器上(去1.4.1,Linux amd64)程序打印

0x400c00
0x400c20

与示例中的值不同,但仍然很低。检查已编译的代码:

$ nm test | grep 'T main.plus'
0000000000400c00 T main.plus
0000000000400c20 T main.plusPlus

这些是函数的实际地址。 func plus只编译了19个字节的代码,因此plusPlus仅出现32个(0x20)字节以满足最佳对齐要求。

为了好奇,这里是func plusobjdump -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   

答案 2 :(得分:2)

它们是函数值:

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))
}

输出:

0x20000
0x20020
3
6