2 回答
TA贡献1824条经验 获得超6个赞
我们可以很容易地查看一些编译后的代码来确认幕后发生了什么。
考虑这个片段:
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 语言的编译器所做的完全相似,只是它的规范仅定义了单个返回值。
TA贡献1780条经验 获得超5个赞
它类似于返回元组,从某种意义上说,某些语言(如 Python)使用元组来实现多个返回值。
但是在 Go 中没有元组这样的东西。返回一个值的函数在堆栈上分配一个槽来保存它。返回两个值的函数在堆栈上分配两个插槽来保存它们。等等…
- 2 回答
- 0 关注
- 161 浏览
添加回答
举报