Warum geht Go beim Schreiben in einen geschlossenen Kanal in Panik?
Man kann das value, ok := <-channel
idiom zum Lesen von Kanälen verwenden, und somit kann das ok-Ergebnis getestet werden, um einen geschlossenen Kanal zu treffen:
Ausgabe:
%Vor%Führen Sie "Lesen vom geschlossenen Kanal" auf Spielplatz
ausDas Schreiben in einen möglicherweise geschlossenen Kanal ist komplizierter, weil Go in Panik gerät, wenn Sie einfach versuchen, zu schreiben, wenn der Kanal geschlossen ist:
%Vor%Ausgabe:
%Vor%Führen Sie "Schreiben in geschlossenen Kanal" auf Spielplatz
ausSoweit ich weiß, gibt es kein einfacheres Idiom, um in einen möglicherweise geschlossenen Kanal ohne Panik zu schreiben. Warum nicht? Was ist der Grund für ein solches asymmetrisches Verhalten zwischen Lesen und Schreiben?
Aus der Go-Sprachspezifikation :
Bei einem Kanal c zeichnet die integrierte Funktion close (c) das nicht mehr auf Werte werden auf dem Kanal gesendet. Es ist ein Fehler, wenn c ein ist Nur-Empfangs-Kanal Senden an oder Schließen eines geschlossenen Kanals verursacht a Laufzeit-Panik. Das Schließen des Nullkanals verursacht auch eine Laufzeitpanik. Nach Aufruf von close und nachdem zuvor gesendete Werte gesendet wurden Empfangene, empfangene Operationen geben den Nullwert für die Channel-Typ ohne Blockierung. Die mehrwertige Empfangsoperation liefert einen empfangenen Wert zusammen mit einer Angabe, ob der Kanal ist geschlossen.
Wenn Sie in einen geschlossenen Kanal schreiben, wird Ihr Programm in Panik geraten. Sie könnten möglicherweise diesen Fehler bei der Wiederherstellung abfangen , wenn Sie dies wirklich tun möchten, aber in einer Situation, in der Sie dies nicht tun ob der Kanal, zu dem du schreibst, offen ist, ist normalerweise ein Zeichen für einen Fehler im Programm.
Einige Zitate:
Hier ist eine Motivation:
Ein Kanal "close" ist wirklich nur ein Senden eines speziellen Wertes auf a Kanal. Es ist ein besonderer Wert, der verspricht, dass keine Werte mehr werden gesendet werden. Es wurde versucht, einen Wert für einen Kanal zu senden, nachdem dieser gesendet wurde closed wird in Panik geraten, da das Senden des Wertes tatsächlich den Garantie durch Schließen. Da ist ein Close nur eine besondere Art von senden, ist es auch nicht erlaubt, nachdem der Kanal geschlossen wurde.
Hier ist ein anderer:
Die einzige Möglichkeit, den Kanal zu schließen, besteht darin, dies dem Leser zu signalisieren sind keine weiteren Werte zu kommen. Das macht nur Sinn, wenn es einen gibt einzelne Quelle von Werten oder wenn mehrere Quellen koordinieren. Dort ist kein sinnvolles Programm, bei dem mehrere Goroutinen einen Kanal schließen ohne zu kommunizieren. Das würde bedeuten, dass mehrere Goroutines Ich wüsste, dass es keine Werte mehr zu senden gibt - wie könnten sie es tun feststellen, dass wenn sie nicht kommunizieren?
(Ian Lance Taylor)
-
Hier ist ein anderer:
Das Schließen eines Kanals gibt ihn als Ressource frei. Es macht keinen Sinn mehr zu Schließen Sie einen Kanal mehrmals, um eine Datei zu schließen Deskriptor mehrmals, oder einen Block zugewiesenen Speicher frei mehrmals. Solche Aktionen bedeuten, dass der Code gebrochen ist, weshalb Schließen eines geschlossenen Kanals löst eine Panik aus.
(Rob Pike)
-
Tags und Links concurrency go channel goroutine panic