Какая разница между "<-chan" и "chan" в качестве возвращаемого типа функции?

Golang новичок здесь.

Существует ли разница между

func randomNumberGenerator() <-chan int {

и

func randomNumberGenerator() chan int {

Я пробовал использовать оба варианта, и они, похоже, отлично работают для меня.

Я видел, как первый использовал Rob Pike (один из разработчиков Go) в своем обсуждении Go Concurrency в Google IO 2012. Я также видел, что он использовался на официальном сайте Go. Зачем добавлять 2 дополнительных символа ( "< -" ), когда вы можете его опустить? Я пробовал искать разницу в Интернете, но не смог найти его.

Ответы

Ответ 1

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

chan   // read-write
<-chan // read only
chan<- // write only

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

func log(<-chan string) { ...

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

Ответ 2

Это пример канала только для передачи.

Необязательный оператор <- указывает направление канала, его отправку или получение. Если направление не указано, канал является двунаправленным. Канал может быть ограничен только для отправки или получения только путем преобразования или назначения.

Полезно рассказать пользователям вашего API, что они должны получать только с этого канала и никогда не отправлять, иначе бывают плохие вещи. Считается хорошей практикой, чтобы указать направление ваших каналов в публичных API. См. Также: Принципы проектирования Go API с каналами.