【问题标题】:Channel of type "set"“set”类型的通道
【发布时间】:2018-11-09 14:20:20
【问题描述】:

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

由于 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 &lt;- {result: true} 的语法无效,这无法编译。我知道这听起来不切实际,因为在这种特殊情况下,我自然可以在 for 循环中创建一个本地映射,并将一个 map[string]bool 对象分配给一个非缓冲通道并返回它,但假设我正在为每个项目创建一个 go 例程在列表中并且真的想使用缓冲通道(而不是使用互斥锁来获取共享映射上的锁)。那么有没有办法在地图通道中插入一个键值对呢?还是我认为这完全错误?

【问题讨论】:

  • 如果值只是一个哨兵,那么只有一个条目的地图是没有意义的。但是,从问题来看,您需要将切片转换为集合(即 map[string]bool),然后然后将地图发送到通道中。

标签: go channel


【解决方案1】:

要直接回答问题,你会想要

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

但这似乎一点用都没有。您可能希望收集地图中的结果,但是当您知道每个结果只有一个元素时,没有理由通过通道传递地图。只需使用string的频道,做

resultsChnl <- result

对于生产者 goroutine 中的每个结果,并且

seenResult[item] = true

在您的消费者循环中收集结果(其中seenResultmap[string]bool)。

或者完全忘记频道,让您的生产者 goroutine 直接写入 sync.Map

【讨论】:

  • 啊。语法很有意义。是的,正如我在问题中提到的,我知道这是不切实际的,我主要只是对语法感到好奇。现在我已经看到了语法,我完全明白为什么我走错了:) 谢谢!
  • sync.Map。很有趣。
  • 补充一点,在 go 中没有 Map.Entry&lt;K, V&gt; 的概念。如果你想将元素对保持在一起,那么你需要创建自己的结构类型来保存它们,然后传递它。
  • 谢谢@Zak。这是有道理的。
猜你喜欢
  • 2015-12-15
  • 2012-09-14
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-07
相关资源
最近更新 更多