2015-01-09 7 views
6

Könnte jemand bitte Klärungswerte geben, die von der Goroutine zurückgegeben werden. Wird der von der Goroutine zurückgegebene Wert auf dem Einsatz gespeichert?Was geschieht mit dem Rückgabewert von goroutine

Beispiel:

// 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) 
    } 

Sollten wir versuchen, die Rückkehr zu vermeiden, gehen Routine bewertet?

Antwort

11

Ein schnell bisschen an dem Montag Ausgang der Suche zeigt

$ go build -gcflags -S z.go 

Die getNumber() Funktion die Ergebnisse speichert auf den Stapel

"".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 , 

Also, wenn es von einem goroutine genannt wird, es tut store seine Ergebnisse auf den Stapel. Dies ist jedoch ein neuer Stapel, der zerstört wird, wenn die Goroutine endet, so dass es keine Möglichkeit gibt, den Rückgabewert abzurufen.

"".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 , 

Es gibt jedoch keine Möglichkeit, diese Ergebnisse abzurufen.

7

Zitiert aus dem Go Language specification: Go statements:

Wenn die Funktion keine Rückgabewerte hat, sie verworfen werden, wenn die Funktion abgeschlossen ist.

So ist es erlaubt, Funktionen mit Rückgabewerte als goroutines auszuführen - es gibt nichts falsch mit ihm ist, und die Spezifikation eindeutig fest, dass ihre Rückgabewerte einfach verworfen werden, wird es keine Störungen verursachen, aber Sie werden nicht Holen Sie es auf die übliche Weise (wie Sie würden, indem Sie die Funktion direkt aufrufen).

0

Werte werden verworfen. Und es gibt nichts Besonderes zu go Aussage. Sie können auch

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

oder nur

... 
getNumber(i) 
... 

sogar

0

Im Gegensatz zu den meisten anderen Programmiersprachen schreiben, gehen Routine nicht Stapel nicht verwendet für Ergebnisspeicher und Adresse zurück. Es hat eine spezielle Speicherzuweisung für das, was sich selbst zerstört, nachdem die Ausführung abgeschlossen ist. Sie können Details darüber in Rob Pikes (Gründer von Golang) sprechen sehen. Besuchen Sie diesen Link für das Youtube-Video: https://www.youtube.com/watch?v=f6kdp27TYZs&index=4&list=LLRA7nvHOCb4nuU7byESOYIg