2013-09-04 13 views
5

Funkcje i metody Go mogą zwracać wiele wartości.Co dokładnie dzieje się, gdy funkcja Go zwraca wiele wartości

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

suma, prod: = learnMultiple (10, 50)

Czy jest podobna do powrotu krotki?

pochodzę rubinowym ziemi, gdzie mogę zwrócić tablicę i

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

nie, po prostu zwraca dwie wartości, a nie krotkę. Dlaczego normalne jest zwracanie wartości 1, ale nie 2? –

+0

Jestem po prostu ciekawy. Nie znalazłem 1 powrotu normalnego. Próbuję tylko zrozumieć, jak powraca. –

Odpowiedz

7

Możemy łatwo spojrzeć na skompilowany kod, aby potwierdzić, co dzieje się za kulisami.

Rozważmy następujący fragment:

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

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

Gdybyśmy demontować utworzonego pliku binarnego ELF, zobaczysz coś takiego (inline został wyłączony więc mogliśmy zobaczyć wywołanie dzieje):

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 
(...) 

Tak więc f po prostu umieszcza wynikowe bajty w stosie, a main odbiera je i umieszcza w rejestrach roboczych. Inny kompilator może również wybrać przekazywanie tych wartości pomiędzy dwoma zakresami bezpośrednio do rejestrów.

Wszystko to jest podobne do tego, co zrobiłby kompilator dla języka C, z wyjątkiem tego, że specyfikacja definiuje tylko jedną wartość zwracaną.

3

Jest ona podobna do powrotu krotki, w tym sensie, że niektóre języki (takie jak pyton) używają krotki wdrożyć wiele wartości zwracanych.

Ale w Go nie ma czegoś takiego jak krotka. Funkcja zwracająca jedną wartość przydziela jeden slot na stosie, aby go zatrzymać. Funkcja zwracająca dwie wartości przydziela dwa miejsca na stosie, aby je zatrzymać. I tak dalej ...

Powiązane problemy