Go語(yǔ)言 多值返回

2020-06-01 10:55 更新

Go語(yǔ)言是支持多值返回的。怎么實(shí)現(xiàn)的呢?讓我們先看一看C語(yǔ)言是如果返回多個(gè)值的。在C中如果想返回多個(gè)值,通常會(huì)在調(diào)用函數(shù)中分配返回值的空間,并將返回值的指針傳給被調(diào)函數(shù)。

int ret1, ret2;
f(a, b, &ret1, &ret2)

被調(diào)函數(shù)被定義為下面形式,在函數(shù)中會(huì)修改ret1和ret2。對(duì)指針參數(shù)所指向的內(nèi)容的修改會(huì)被返回到調(diào)用函數(shù),用這種方式實(shí)現(xiàn)多值返回。

void f(int arg1, int arg2, int *ret1, int *ret2);

所以,從表面上看Go的多值返回只不過像是這種實(shí)現(xiàn)方式的一個(gè)語(yǔ)法糖衣。其實(shí)簡(jiǎn)單的這么理解也沒什么影響,但實(shí)際上Go不是這么干的,Go和我們常用的C編譯器的函數(shù)調(diào)用協(xié)議是不同的。

假設(shè)我們定義一個(gè)Go函數(shù)如下:

func f(arg1, arg2 int) (ret1, ret2 int)

Go的做法是在傳入的參數(shù)之上留了兩個(gè)空位,被調(diào)者直接將返回值放在這兩空位,函數(shù)f調(diào)用前其內(nèi)存布局是這樣的:

為ret2保留空位
為ret1保留空位
參數(shù)3
參數(shù)2
參數(shù)1  <-SP 

調(diào)用之后變?yōu)椋?/p>

為ret2保留空位
為ret1保留空位
參數(shù)2
參數(shù)1  <-FP
保存PC <-SP
f的棧
...

3

Go的C編譯器按是plan9的C編譯器實(shí)現(xiàn)的,在被調(diào)函數(shù)中對(duì)參數(shù)值的修改是會(huì)返回到調(diào)用函數(shù)中的。在函數(shù)體中設(shè)置ret1和ret2的值,實(shí)際上會(huì)被編譯成這樣:

MOVQ    BX,ret1+16(FP)
...
MOVQ    BX,ret2+24(FP)

對(duì)ret1+16(FP)的賦值其實(shí)是修改的調(diào)用函數(shù)的棧中的內(nèi)容,這樣就會(huì)將結(jié)果返回給調(diào)用函數(shù)了。這就是Go和C函數(shù)調(diào)用協(xié)議中很重要的一個(gè)區(qū)別:為了實(shí)現(xiàn)多值返回,Go是使用棧空間來(lái)返回值的。而常見的C語(yǔ)言是通過寄存器來(lái)返回值的。

links


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)