代码之家  ›  专栏  ›  技术社区  ›  Arian Motamedi

“SET”型信道

  •  0
  • Arian Motamedi  · 技术社区  · 8 年前

    我最近开始用c_编程多年,现在很难把自己的脑袋放在语言的几个概念上。下面是我试图解决的一个例子:我希望能够创建一个在列表上迭代的例程,调用一个函数,并将输出存储在一个缓冲通道中。问题是我想返回 不同的 这些输出值的集合,因为函数可以为列表中的两个不同元素返回相似的结果。

    因为go没有内置的set类型,所以我尝试使用 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循环中创建一个本地映射并分配一个 映射[字符串]布尔 对象到一个非缓冲通道并返回该值,但假设我正在为列表中的每个项创建一个go例程,并且确实希望使用缓冲通道(而不是使用互斥锁来获取共享映射上的锁)。那么有没有办法在map通道中插入一个键值对呢?或者我想的完全不对?

    1 回复  |  直到 8 年前
        1
  •  3
  •   hobbs    8 年前

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

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

    但这似乎一点用都没有。你可能想 收集 结果在一个map中,但是当您知道每个结果只有一个元素时,没有理由在通道上传递一个map。只需使用 string

    resultsChnl <- result
    

    对于你的制作人Goroutine的每一个结果,

    seenResult[item] = true
    

    在消费者循环中收集结果(在 seenResult 是一个 map[string]bool )

    或者完全忘记这个频道,让你的制作人直接写一个 sync.Map .