Подтвердить что ты не робот

Различные способы передачи каналов в качестве аргументов в функции go (golang)

Я читал некоторый код go и говорил несколько разных способов передать каналы go. Возможно, они такие же, но мне было интересно, есть ли какая-либо разница, поскольку я не мог найти документацию в Интернете:

1)

func serve(ch <-chan interface{}){ //do stuff }

2)

func serve(ch chan<- interface{}){ //do stuff }

3)

func serve(ch chan interface{}){ //do stuff }

4)

func server(ch *chan interface{}){ //do stuff}

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

ПРИМЕЧАНИЕ. Я знаю, что нет никаких оснований передавать указатель на chan, map или slice или значение функции, поскольку это все ссылочные типы, которые внутри содержат указатель (исключение было бы, если вы хотите, чтобы вызываемый, чтобы изменить заголовок ссылочного типа). Единственная причина, по которой я предоставил ее, - это полнота (то есть действительно обеспечить каждый способ передачи канала в качестве параметра и поставить вопрос, который, надеюсь, ссылается на все способы сделать это и сравнивает их).

4b9b3361

Ответ 1

Это разные типы типов. См. http://golang.org/ref/spec#Channel_types. Для материала указателя: Необычно, но может быть полезно, если вы хотите изменить канал изнутри функции (никогда не видел этого в дикой природе).

Ответ 2

Я всегда рекомендую, чтобы направление передавалось везде, где это возможно, например

func serve(ch <-chan SomeType) { /*do stuff*/ }

func serve(ch chan<- SomeType) { /*do stuff*/ }

Включая стрелку <-chan или chan<-, вы достигаете трех вещей:

  • Вы даете понять, что этот параметр является end для канала.
  • Вы четко выражаете , который поставляется.
  • Вы даете больше информации компилятору для проверки. Если тело функции пытается использовать неправильный конец канала, компилятор может вызвать ошибку.

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

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

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

Ответ 3

Правило большого пальца: Стрелка показывает, поступают ли данные (выводятся) или выходят из (входного) канала. Никакая стрелка не является каналом общего назначения.

chan <-          writing to channel (output channel)
<- chan          reading from channel (input channel)
chan             read from or write to channel (input/output channel)