2015-01-09 11 views
6

Czy ktoś mógłby podać wartość wyjaśnienia zwróconą przez Goroutine. Czy zwrócona wartość z goroutine jest zapisywana na stosie.Co stanie się z wartością zwracaną z goroutine

przykład:

// function getNumber returns the "int i" and we can't use this returned value 
// because this function is invoked as goroutine. 
// We know that, to communicate between main and goroutine one could 
// use the channel (chan <- i), but I am interested to know about 
// the use of return i in goroutine. Is it possible to get/ use this 
// returned value. 
func getNumber(i int) int { 
    return i 
    } 

func main() { 

    for i:=0; i<10; i++ { 
     go printNumber(i) 
     } 
    time.Sleep(5) 
    } 

powinniśmy starać się unikać powrotu wartościową Przejdź rutyny?

Odpowiedz

11

Szybkie trochę patrząc na montażowej pokazuje

$ go build -gcflags -S z.go 

Funkcja getNumber() ma przechowywać swoje wyniki do stosu

"".getNumber t=1 size=16 value=0 args=0x10 locals=0x0 
    0x0000 00000 (z.go:5) TEXT "".getNumber+0(SB),4,$0-16 
    0x0000 00000 (z.go:6) MOVQ "".i+8(FP),BX 
    0x0005 00005 (z.go:6) MOVQ BX,"".~r1+16(FP) 
    0x000a 00010 (z.go:6) RET , 

Więc kiedy jest ona wywoływana z goroutine, robi sklep jego wyniki do stosu. Jest to jednak nowy stos, który jest niszczony, gdy kończy się goroutine, więc nie ma możliwości odzyskania wartości zwracanej.

"".main t=1 size=96 value=0 args=0x0 locals=0x18 
    0x0000 00000 (z.go:9) TEXT "".main+0(SB),$24-0 
    0x0000 00000 (z.go:9) MOVQ (TLS),CX 
    0x0009 00009 (z.go:9) CMPQ SP,16(CX) 
    0x000d 00013 (z.go:9) JHI ,22 
    0x000f 00015 (z.go:9) CALL ,runtime.morestack_noctxt(SB) 
    0x0014 00020 (z.go:9) JMP ,0 
    0x0016 00022 (z.go:9) SUBQ $24,SP 
    0x001a 00026 (z.go:10) MOVQ $0,AX 
    0x001c 00028 (z.go:10) CMPQ AX,$10 
    0x0020 00032 (z.go:10) JGE $0,74 
    0x0022 00034 (z.go:11) MOVQ AX,"".i+16(SP) 
    0x0027 00039 (z.go:11) MOVQ AX,(SP) 
    0x002b 00043 (z.go:11) MOVQ $"".getNumber·f+0(SB),CX 
    0x0032 00050 (z.go:11) PUSHQ CX, 
    0x0033 00051 (z.go:11) PUSHQ $16, 
    0x0035 00053 (z.go:11) PCDATA $0,$0 
    0x0035 00053 (z.go:11) CALL ,runtime.newproc(SB) 
    0x003a 00058 (z.go:11) POPQ ,CX 
    0x003b 00059 (z.go:11) POPQ ,CX 
    0x003c 00060 (z.go:10) MOVQ "".i+16(SP),AX 
    0x0041 00065 (z.go:10) INCQ ,AX 
    0x0044 00068 (z.go:10) NOP , 
    0x0044 00068 (z.go:10) CMPQ AX,$10 
    0x0048 00072 (z.go:10) JLT $0,34 
    0x004a 00074 (z.go:13) MOVQ $5,(SP) 
    0x0052 00082 (z.go:13) PCDATA $0,$0 
    0x0052 00082 (z.go:13) CALL ,time.Sleep(SB) 
    0x0057 00087 (z.go:14) ADDQ $24,SP 
    0x005b 00091 (z.go:14) RET , 

Jednak nie ma możliwości odzyskania tych wyników.

7

Cytując z Go Language specification: Go statements:

Jeśli funkcja ma żadnych wartości zwracanych, są odrzucane, gdy funkcja kończy.

Dozwolone jest więc wykonywanie funkcji z wartościami zwracanymi jako goroutines - nie ma w tym nic złego, a specyfikacja wyraźnie stwierdza, że ​​ich wartości zwracane są po prostu odrzucane, nie spowoduje to żadnego błędu, ale nie będzie weź to w zwykły sposób (tak jak robisz to bezpośrednio wywołując funkcję).

0

Wartości są odrzucane. I nie ma nic szczególnego w oświadczeniu go. Można również napisać

... 
_ = getNumber(i) 
... 

lub po prostu

... 
getNumber(i) 
... 

nawet

0

W przeciwieństwie do większości innych języków programowania, Go rutyna nie używa stosu do przechowywania wynik i adres zwrotny. Ma specjalny przydział pamięci dla tego, który niszczy się po zakończeniu wykonywania. możesz zobaczyć szczegóły na ten temat w rozmowie Rob Pike'a (założyciela golangu). odwiedź ten link do filmu na youtube: https://www.youtube.com/watch?v=f6kdp27TYZs&index=4&list=LLRA7nvHOCb4nuU7byESOYIg

Powiązane problemy