“set”类型的频道

时间:2018-05-30 16:31:00

标签: go channel

我最近在使用C#编程多年后开始编写Go,并且我很难围绕语言的几个概念。这是我想要解决的一个例子:我希望能够创建一个迭代列表,调用函数并将输出存储在缓冲通道中的例程。问题是我想返回一个不同这些输出值的集合,因为该函数可以为列表中的两个不同元素返回类似的结果。

由于Go没有内置的设置类型,我尝试使用map[string]bool来存储不同的值(使用map[string]boolmap[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 :(得分:3)

要直接回答这个问题,你需要

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

但这似乎没什么用处。您可能希望在地图中收集结果,但是当您知道每个结果只有一个元素时,没有理由在通道上传递地图。只需使用string频道,即

resultsChnl <- result

表示生产者goroutine中的每个结果,

seenResult[item] = true
在您的消费者循环中

收集结果(seenResultmap[string]bool)。

或完全忘掉频道,让你的制作人goroutines直接写入sync.Map