GoRoutine, который возвращает два канала - PullRequest
0 голосов
/ 07 января 2019

Может кто-нибудь помочь мне понять, как интерпретировать следующую строку кода в функции return - (_, _ <-chan interface {}) </b>

Я понимаю, что функция возвращает два канала. Но я не понимаю, как это достигается с помощью следующего (_, _ <-chan interface {}). Какая разница, если я просто поменяю его на (<-chan interface {}, <-chan interface {})? </p>

tee := func(
    done <-chan interface{},
    in <-chan interface{},
) (_, _ <-chan interface{}) {
    out1 := make(chan interface{})
    out2 := make(chan interface{})

    go func() {
        defer close(out1)
        defer close(out2)

        for val := range orDone(done, in) {
            var out1, out2 = out1, out2
            for i := 0; i < 2; i++ {
                select {
                case <-done:
                case out1 <- val:
                    out1 = nil
                case out2 <- val:
                    out2 = nil
                }
            }
        }
    }()
    return out1, out2
}`

Ответы [ 2 ]

0 голосов
/ 07 января 2019

(_, _ <-chan interface{}) эквивалентно (<-chan interface{}, <-chan interface{}). Различий нет, кроме длины исходного кода и читабельности.

  1. Мы начинаем с (<-chan interface{}, <-chan interface{}) типов возвращаемых значений.
  2. Поскольку возвращаемые значения могут иметь имена, можно написать (ch1 <-chan interface{}, ch2 <-chan interface{}), чтобы вернуть те же 2 канала.
  3. Последовательность аргументов (или возвращаемых значений) с одинаковыми типами может опускать типы для всех переменных, кроме последней. Следовательно, наши типы возврата становятся: (ch1, ch2 <-chan interface{})
  4. И поскольку нам на самом деле не нужны имена возвращаемых значений, мы можем заменить имена подчеркиванием, сделав их снова анонимными: (_, _ <-chan interface{})

Вуаля! Читаемая пара каналов одного типа.

0 голосов
/ 07 января 2019

Это func декларация

FunctionType   = "func" Signature .
Signature      = Parameters [ Result ] .
Result         = Parameters | Type .
Parameters     = "(" [ ParameterList [ "," ] ] ")" .
ParameterList  = ParameterDecl { "," ParameterDecl } .
ParameterDecl  = [ IdentifierList ] [ "..." ] Type .

Как видите, Result подобен параметрам метода a Parameters, который в свою очередь сводится к IdentifierList. Идет пустой идентификатор _, который может заменить каждый идентификатор в IdentifierList.

Первоначальный автор использовал это вместе с синтаксисом «несколько идентификаторов, объявленных для одного и того же типа», чтобы создать - как уже упоминалось - странное для чтения объявление двух возвращаемых значений одного и того же типа.

См. https://golang.org/ref/spec#Function_declarations

Вы также можете реализовать функции, которые «удаляют» параметры, используя для них пустой идентификатор. Может пригодиться, когда вам не нужен параметр интерфейса, который вы реализуете.

func foo(a string, _ int, b string) { ... }

Второй параметр недоступен для использования.

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