Warum ist es nicht möglich, einen Rückgabewert von einer Goroutine abzurufen, die ihn einer Variablen zuweist?
Goroutine ausführen (asynchron) und Rückgabewert von Funktion abrufen sind im Wesentlichen widersprüchliche Aktionen. Wenn Sie sagen, go
Sie meinen "asynchron machen" oder noch einfacher: "Weiter! Warten Sie nicht, bis die Funktionsausführung abgeschlossen ist". Wenn Sie jedoch einer Variablen einen Funktionsrückgabewert zuweisen, erwarten Sie, dass dieser Wert in der Variablen enthalten ist. Wenn Sie das tun, x := go doSomething(arg)
sagen Sie: "Weiter, warten Sie nicht auf die Funktion! Warten-warten-warten! Ich brauche einen zurückgegebenen Wert, der in x
var direkt in der nächsten Zeile unten verfügbar ist!"
Kanäle
Der natürlichste Weg, einen Wert von einer Goroutine abzurufen, sind Kanäle. Kanäle sind die Rohre, die gleichzeitige Goroutinen verbinden. Sie können Werte von einer Goroutine in Kanäle senden und diese Werte in eine andere Goroutine oder in einer synchronen Funktion empfangen. Sie können leicht einen Wert von einer Goroutine erhalten, die die Parallelität nicht unterbricht, indem Sie select
:
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
Das Beispiel stammt aus Go By Example
CSP & Message-Passing
Go basiert größtenteils auf der CSP-Theorie . Die naive Beschreibung von oben könnte in Bezug auf CSP genau umrissen werden (obwohl ich glaube, dass dies nicht in Frage kommt). Ich empfehle dringend, sich mit der CSP-Theorie vertraut zu machen, zumindest weil es sich um RAD handelt. Diese kurzen Zitate geben eine Denkrichtung vor:
Wie der Name schon sagt, ermöglicht CSP die Beschreibung von Systemen anhand von Komponentenprozessen, die unabhängig voneinander arbeiten und ausschließlich durch Kommunikation über die Weitergabe von Nachrichten miteinander interagieren .
In der Informatik sendet die Nachrichtenübermittlung eine Nachricht an einen Prozess und stützt sich auf den Prozess und die unterstützende Infrastruktur, um den tatsächlich auszuführenden Code auszuwählen und aufzurufen. Das Weiterleiten von Nachrichten unterscheidet sich von der herkömmlichen Programmierung, bei der ein Prozess, eine Unterroutine oder eine Funktion direkt mit Namen aufgerufen wird.