为了账号安全,请及时绑定邮箱和手机立即绑定

当 Go 返回多个值时到底发生了什么

当 Go 返回多个值时到底发生了什么

Go
冉冉说 2021-06-25 18:10:30
Go 函数和方法可以返回多个值。func learnMultiple(x, y int) (sum, prod int) {    return x + y, x * y // return two values}sum, prod := learnMultiple(10, 50)它类似于返回元组吗?我来自红宝石之地,在那里我可以返回一个数组和一个sum, prod = ["60","500"]
查看完整描述

2 回答

?
慕妹3242003

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 语言的编译器所做的完全相似,只是它的规范仅定义了单个返回值。


查看完整回答
反对 回复 2021-06-28
?
翻阅古今

TA贡献1780条经验 获得超5个赞

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

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


查看完整回答
反对 回复 2021-06-28
  • 2 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信