2015-07-06 9 views
14

NB: Dies ist kein Duplikat von this Frage, weil ich verstehe, wenn Sie einseitig gerichtete Kanäle verwenden würden. Das mache ich die ganze Zeit. Meine Frage ist, warum dieses Programm gilt:Gibt es einen Zweck, einen eindirektionalen Kanal zu "machen"?

func main() { 
    ch := make(chan<- int) 
    ch <- 5 
    fmt.Println("Hello, playground") 
} 

Playground

Lauf es, natürlich, eine Sackgasse gibt. Wenn Sie den Typ mit% T überprüfen, meldet Go tatsächlich, dass der Typ ch ein Nur-Senden-Kanal ist. In Go darf man make unidirektionale Kanäle haben, aber es macht wenig Sinn, weil man bei der Erstellung eines Kanals, der anfänglich nur in einer Richtung ist, sicherstellt, dass mindestens einer von Lese-/Schreibvorgängen niemals auftritt.

Eine mögliche Erklärung wäre, eine Goroutine zum Aufhängen zu zwingen, aber das ist genauso einfach mit select {}.

Meine einzige andere Idee ist es, eine goroutine zu zwingen, nur etwas n mal zu tun,

ch := make(chan<- int, 50) 
// do something 50 times, since then the buffer is full 
for { 
    ch <- doSomething() 
} 

Aber das ist leichter, nicht weniger verwirrend mit einer beliebigen Anzahl von verschiedenen Konstruktionen erreicht zu erwähnen.

Ist das nur eine Eigenart des Typsystems, oder gibt es für dieses Verhalten keine Verwendung, an die ich nicht denke?

+1

ich eine der Design-Ziele von Go Einfachheit glauben ist. Die Sprachspezifikation ist sehr kurz. Ich glaube, dass dies ein Beispiel für Einfachheit auf Kosten von Nonsense-Konstrukten sein könnte. – ReyCharles

+2

@ReyCharles Ich würde akzeptieren, dass, warum, sagen, 'var ch chan <- int = machen (chan int)' ist gültig, aber 'make 'ist so ein besonderes Konstrukt, dessen Verhalten ist ziemlich klar und ausführlich in der Spezifikation Ich denke, es ist eher ein Versehen als eine Folge der Einfachheit. – LinearZoetrope

+8

Ich denke, das ist etwas, was du niemals tun würdest. (Oder, zumindest, jemand, der eine Verwendung dafür findet, gewinnt die heutige Runde von Go Pub Trivia ™.) Aber im Einklang mit dem, was @ReyCharles sagte, sind Spezifikationen nicht erforderlich, um alle Nonsense-Konstrukte auszuschließen. Go versucht, einige Formen von Unsinn zu verhindern, die C nicht hat (z. B. unbenutzte vars); Rust hat statische Checks, die versuchen, etwas Unsinn auszuschließen. Go erstellt glücklich (z. B. Rassen). Das ist in Ordnung, und wir kichern über die gelegentliche Seltsamkeit und versuchen, etwas aufzubauen. – twotwotwo

Antwort

3

Sie haben eine Sprache: Wörter (Tokens) und eine Grammatik. Sie können immer gültigen Unsinn schreiben: Blau ist keine Farbe.

Sie schrieb einigen gültigen Unsinn:

package main 

func main() { 
    ch := make(chan<- int) 
    ch <- 5 
} 

hier etwas mehr gültig Unsinn:

package main 

func main() { 
    for { 
    } 
} 
Verwandte Themen