NB: Questo non è un duplicato della domanda this, perché capisco quando si utilizzano i canali unidirezionali. Lo faccio sempre. La mia domanda è: perché questo programma è valido:Esiste uno scopo per "rendere" un canale unidirezionale?
func main() {
ch := make(chan<- int)
ch <- 5
fmt.Println("Hello, playground")
}
esecuzione, naturalmente, dà una situazione di stallo. Se si controlla il tipo con% T, Go riporta infatti che il tipo di ch
è un canale di sola invio. In Go, sei autorizzato a make
canali unidirezionali, ma ha poco senso perché, rendendo un canale che al suo inizio è a senso unico, stai assicurando che almeno uno di lettura/scrittura non si verificherà mai.
Una possibile spiegazione potrebbe essere quella di forzare una goroutine a bloccarsi, ma ciò è altrettanto semplice con select {}
.
La mia unica altra idea è quella di forzare un goroutine di fare solo qualcosa n
volte,
ch := make(chan<- int, 50)
// do something 50 times, since then the buffer is full
for {
ch <- doSomething()
}
Ma che è più facile, per non parlare di meno confusamente, realizzato con qualsiasi numero di differenti costruzioni.
Si tratta solo di una stranezza/svista del sistema di tipi, o si usa per questo comportamento a cui non sto pensando?
Credo che uno degli obiettivi di progettazione di Go è la semplicità. Le specifiche del linguaggio sono molto brevi. Credo che questo potrebbe essere un esempio di semplicità a costo di costrutti senza senso. – ReyCharles
@ReyCharles Accetterei che per il motivo, per esempio, 'var ch chan <- int = make (chan int) 'è valido, ma' make' è un costrutto così speciale il cui comportamento è piuttosto chiaramente e comprensibilmente enunciato nelle specifiche penso che sia più una svista che una conseguenza della semplicità. – LinearZoetrope
Penso che sia una cosa che non vorresti mai fare. (O, almeno, qualcuno che ne viene a conoscenza vince il round di Go Pub Trivia ™ di oggi.) Ma sulla falsariga di quanto affermato da @ReyCharles, le specifiche non sono necessarie per escludere tutti i costrutti senza senso. Go tenta di prevenire alcune forme di sciocchezze che C non possiede (ad esempio, vars inutilizzati); La ruggine ha dei controlli statici che tentano di escludere alcune sciocchezze che vanno allegramente compilate (ad es. Gare). Va bene, e soprattutto ridacchiamo per la stranezza occasionale e passiamo a cercare di costruire cose. – twotwotwo