Почему тип канала имеет в нем "<-"?

Это работает.

var tick <-chan time.Time = time.Tick(1e8)

Однако это не так.

var tick chan time.Time = time.Tick(1e8)

Зачем мне нужен <- в объявлении типа для канала? Я думал, что <- предназначен для записи или чтения из канала. Почему это должно появиться в типе?

Ответ 1

Каналы могут иметь тип, указывающий, является ли он только для чтения, writeonly или обоих.

Указание направления канала выполняется с помощью < - как часть типа или опущено для канала чтения/записи.

Таким образом, <- in <-chan time.Time является частью типа,

chan   time.Time  //Would be a read/writable channel
chan<- time.Time  // Would be a write only channel
<-chan time.Time  // Would be a read only channel

и time.Tick(1e8) возвращает канал только для чтения.

Подробнее в описании языка здесь

Ответ 2

Хороший способ думать о каналах - это трубы с двумя концами. Один конец - это то, где происходят события, а другой - те, из которых они вытекают. Таким образом, объявление канала, например

var c = make(chan int)

создает канал в целом, т.е. с обоими концами. С другой стороны,

func consume(c <-chan int) {
    ...
}

определяет функцию с входным параметром канала, то есть читаемым концом канала, и

func generate(c chan<- int) {
    ...
}

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

Тот же общий принцип применяется, когда каналы используются как локальные переменные или как поля в структурах.

Хорошая практика использовать синтаксис конца канала, где это возможно, потому что компилятор сможет более тщательно проверить, что вы написали то, что вы намеревались.

Интересно, что язык программирования occum также имеет эквивалентный синтаксис для обозначения того, какой конец канала есть.

Ответ 3

Пока вы можете объявить фактическую "только для чтения" или "только для записи", это бесполезно, потому что вы ничего не можете с ними поделать.

Синтаксис "только для чтения" и "только для записи" предназначен для параметров функции. Этот синтаксис больше похож на "const" в C или "in" и "out" в Ada.

Каналы "Не идут" имеют два "конца". Трубы UNIX имеют два дескриптора файлов, по одному для каждого конца. Для чтения и записи используется та же переменная типа канала.