Go返回多个值时究竟发生了什么

时间:2013-09-04 19:57:18

标签: go

Go函数和方法可以返回多个值。

func learnMultiple(x, y int) (sum, prod int) {
    return x + y, x * y // return two values
}

总和,prod:= learnMultiple(10,50)

它与返回元组类似吗?

我来自红宝石之地,在那里我可以返回一个数组和一个

sum, prod = ["60","500"]

2 个答案:

答案 0 :(得分:8)

我们可以轻松查看一些已编译的代码,以确认幕后发生了什么。

请考虑以下代码段:

func f() (a, b byte) {
    return 'x', 'y'
}

func main() {
    a, b := f()
    println(a, b)
}

如果我们反汇编创建的ELF二进制文件,你会看到类似的东西(内联被禁用,所以我们可以看到调用正在发生):

0000000000400c00 <main.f>:
400c00:       c6 44 24 08 78          movb   $0x78,0x8(%rsp)
400c05:       c6 44 24 09 79          movb   $0x79,0x9(%rsp)
400c0a:       c3                      retq

0000000000400c10 <main.main>:
(...)
400c25:       48 83 ec 10             sub    $0x10,%rsp
400c29:       e8 d2 ff ff ff          callq  400c00 <main.f>
400c2e:       48 0f b6 1c 24          movzbq (%rsp),%rbx
400c33:       48 89 d8                mov    %rbx,%rax
400c36:       48 0f b6 5c 24 01       movzbq 0x1(%rsp),%rbx
(...)

因此f只是将结果字节放入堆栈中,main将它们选回并将它们放入工作寄存器中。不同的编译器也可能选择将这两个范围之间的值直接传递给寄存器。

这类似于C语言的编译器所做的,除了它的规范只定义了一个返回值。

答案 1 :(得分:3)

它类似于返回一个元组,在某种意义上,某些语言(如python)使用元组来实现多个返回值。

但是在Go中没有像元组这样的东西。返回一个值的函数会在堆栈上分配一个插槽来保存它。返回两个值的函数会在堆栈上分配两个插槽来保存它们。等等...