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

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"]


冉冉说
浏览 162回答 2
2回答

慕妹3242003

我们可以很容易地查看一些编译后的代码来确认幕后发生了什么。考虑这个片段:func f() (a, b byte) {&nbsp; &nbsp; return 'x', 'y'}func main() {&nbsp; &nbsp; a, b := f()&nbsp; &nbsp; println(a, b)}如果我们反汇编创建的 ELF 二进制文件,您将看到如下内容(内联被禁用,因此我们可以看到调用发生):0000000000400c00 <main.f>:400c00:&nbsp; &nbsp; &nbsp; &nbsp;c6 44 24 08 78&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movb&nbsp; &nbsp;$0x78,0x8(%rsp)400c05:&nbsp; &nbsp; &nbsp; &nbsp;c6 44 24 09 79&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movb&nbsp; &nbsp;$0x79,0x9(%rsp)400c0a:&nbsp; &nbsp; &nbsp; &nbsp;c3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; retq0000000000400c10 <main.main>:(...)400c25:&nbsp; &nbsp; &nbsp; &nbsp;48 83 ec 10&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sub&nbsp; &nbsp; $0x10,%rsp400c29:&nbsp; &nbsp; &nbsp; &nbsp;e8 d2 ff ff ff&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; callq&nbsp; 400c00 <main.f>400c2e:&nbsp; &nbsp; &nbsp; &nbsp;48 0f b6 1c 24&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; movzbq (%rsp),%rbx400c33:&nbsp; &nbsp; &nbsp; &nbsp;48 89 d8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; mov&nbsp; &nbsp; %rbx,%rax400c36:&nbsp; &nbsp; &nbsp; &nbsp;48 0f b6 5c 24 01&nbsp; &nbsp; &nbsp; &nbsp;movzbq 0x1(%rsp),%rbx(...)所以f只需将结果字节放在堆栈中,然后将main它们取回并将它们放入工作寄存器中。不同的编译器也可能选择将这些值在两个作用域之间直接传递到寄存器中。这与 C 语言的编译器所做的完全相似,只是它的规范仅定义了单个返回值。

翻阅古今

它类似于返回元组,从某种意义上说,某些语言(如 Python)使用元组来实现多个返回值。但是在 Go 中没有元组这样的东西。返回一个值的函数在堆栈上分配一个槽来保存它。返回两个值的函数在堆栈上分配两个插槽来保存它们。等等…
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go