Канал типа "набор" - PullRequest
0 голосов
/ 30 мая 2018

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

Поскольку Go не имеет встроенной- в наборе типов я пытаюсь использовать map[string]bool для хранения различных значений (использование map[string]bool или map[string]struct - это то, что другие предложили в качестве замены набора);и я использую буферизованный канал для вставки в эту карту, однако я не уверен, как будет выглядеть правильный синтаксис для вставки 1 элемента в карту.Вот что я пытаюсь сделать:

resultsChnl := make(chan map[string]bool, len(myList))
go func(myList []string, resultsChnl chan map[string]bool) {
    for _, item := range myList {

        result, err := getResult(item)
        /* error checking */

        resultsChnl <- {result: true}
    }

    close(resultsChnl)
}(myList, resultsChnl)

for item := range resultsChnl {
    ...
}

Очевидно, что это не компилируется из-за неверного синтаксиса resultsChnl <- {result: true}.Я знаю, это звучит непрактично, поскольку, естественно, в этом конкретном случае я мог бы создать локальную карту внутри цикла for и назначить один объект map[string]bool небуферизованному каналу и вернуть его, но давайте предположим, что я создавал подпрограмму go для каждого элементав списке и действительно хотел использовать буферизованный канал (в отличие от использования мьютекса, чтобы захватить блокировку на общей карте).Так есть ли способ вставить одну пару ключ-значение в канал карты?Или я думаю об этом совершенно неправильно?

1 Ответ

0 голосов
/ 30 мая 2018

Чтобы ответить на вопрос напрямую, вы бы хотели

resultsChnl <- map[string]bool{result: true}

Но это не кажется полезным вообще.Возможно, вы захотите собрать результатов на карте, но нет никакой причины передавать карту по каналу для каждого результата, если вы знаете, что в нем будет только один элемент.Просто используйте канал string, выполните

resultsChnl <- result

для каждого результата в вашей программе продюсера и

seenResult[item] = true

в цикле вашего потребителя, чтобы собрать результаты (где seenResultmap[string]bool).

Или полностью забудьте о канале, и пусть ваши продюсеры записывают напрямую в sync.Map .

...