2015-07-06 2 views
14

NB: Это не дубликат вопроса this, потому что я понимаю, когда вы будете использовать однонаправленные каналы. Я делаю это все время. Мой вопрос, почему эта программа действует:Есть ли цель «сделать» однонаправленный канал?

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

Playground

Запуск это, конечно, дает в тупик. Если вы проверите тип с% T, Go действительно сообщит, что тип ch является каналом только для отправки. В Go вам разрешено использовать однонаправленные каналы make, но это мало смысла, потому что, создав канал, который на момент его создания является однонаправленным, вы гарантируете, что хотя бы одно из чтения/записи никогда не произойдет.

Возможное объяснение заключается в том, чтобы заставить goroutine висеть, но это так же легко достигается с помощью select {}.

Моя единственная другая идея заключается в том, чтобы заставить goroutine только сделать что-то n раз,

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

Но это легко, не говоря уже о менее смутно, осуществляется с любым количеством различных конструкций.

Это просто причуда/надзора над системой типов, или она используется для такого поведения, о котором я не думаю?

+1

Я считаю, что одна из целей проекта Go является простота. Спецификация языка очень короткая. Я считаю, что это может быть примером простоты за счет бессмысленных конструкций. – ReyCharles

+2

@ReyCharles Я бы согласился, что для почему, скажем, 'var ch chan <- int = make (chan int)' действительно, но 'make' - это такая специальная конструкция, поведение которой довольно четко и всесторонне прописано в спецификации что я думаю, что это скорее надзор, чем следствие простоты. – LinearZoetrope

+8

Я думаю, что это то, чего вы никогда не захотите делать. (Или, по крайней мере, кто-то, кто придумал для этого, выигрывает сегодняшний раунд Go Pub Trivia ™.) Но в соответствии с тем, что сказал @ReyCharles, спецификации не обязаны исключать все бессмысленные конструкции. Go пытается предотвратить некоторые формы глупостей, которые C не (например, неиспользованные вары); У ржавчины есть статические проверки, которые пытаются исключить какую-то бессмысленность Go, с удовольствием компилируется (например, гонки). Все в порядке, и мы в основном хихикаем от случайной странности и переходим к попытке построить материал. – twotwotwo

ответ

3

У вас есть язык: слова (жетоны) и грамматика. Вы всегда можете написать действительную глупость: синий цвет не цвет.

Вы писали некоторые действительные нонсенс:

package main 

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

Вот некоторые более справедливы нонсенс:

package main 

func main() { 
    for { 
    } 
}