Go中与std::set相对应的是什么?

huangapple go评论84阅读模式
英文:

Go equivalent to std::set?

问题

在Go语言中,与std::set相对应的是什么?请注意,只有唯一性是重要的,我不关心顺序。

我考虑过使用虚拟类型,比如map[string]bool(其中bool是虚拟类型),然而在Go语言中,我经常发现需要提供一个不需要的类型,比如将通道用作信号量,在这种情况下。我是否遗漏了Go语言中的某些惯用方法?

英文:

What would be the equivalent in Go to a std::set? Note that only uniqueness is important, I don't care about ordering.

I've considered using dummy type, such as map[string]bool (where bool is the dummy), however often I find in Go I need to provide a type where one is not required, such as a channel used as a semaphore, and this case. Am I missing something idiomatic to Go?

答案1

得分: 6

在像Perl这样没有集合的语言中,使用带有虚拟值的映射作为集合是常见的做法。我认为这是一种在Go中获取集合的可接受方式,除非你想自己实现它或使用一些第三方实现。当然,你的数据类型必须是允许作为映射键的类型,即不能是结构体、数组或切片。

英文:

Using a map with dummy values as a set is common practice in languages like Perl, which do not have sets. I think it is an acceptable way to get sets in Go, unless you want to implement it yourself or use some third-party implementation. Of course, your datatype has to be one that is allowed as the key in a map, i.e. not struct, array, or slice.

答案2

得分: 3

使用map[string]bool是完全可以的。

还有一些更高级的库可以处理集合,例如:https://github.com/pwil3058/gosets

但我仍然会坚持使用简单的map,它更符合惯用法并且更简单,这总是好的。

英文:

Using map[string]bool is perfectly fine.

There are also some more fancy libraries to handle sets, see for example: https://github.com/pwil3058/gosets

But I would still stick with a simple map, it is more idiomatic and simpler, which is always good.

答案3

得分: 2

使用map[string]bool(将true作为虚拟值)或map[string]struct{}作为集合被认为是Go语言中的惯用方式。它们各自有优缺点。

假设:

b := make(map[string]bool)
s := make(map[string]struct{})
  1. 使用b更容易检查集合是否包含元素:

    if b["x"] {
        // b包含"x"
    }
    
    if _, ok := s["x"]; ok {
        // s包含"x"
    }
    
  2. 除非你能保证b不包含任何false值,否则使用s更容易遍历元素:

    for e, v := range b {
        if v {
            // e是b的元素
        }
    }
    
    for e := range s {
        // e是s的元素
    }
    
  3. sb更节省内存。

作为替代方案,你可以使用开源库。例如:

当然,目前在Go中无法实现通用集合。但是随着计划中将泛型引入Go的版本更新,将来将有可能实现(最早在1.17版本之后)。

英文:

Using map[string]bool (with true as the dummy value) or map[string]struct{} as a set is considered idiomatic Go. Each of them has its own pros and cons.

Assume:

b := make(map[string]bool)
s := make(map[string]struct{})
  1. Checking whether a set has an element is easier with b:

    if b["x"] {
    	// b has "x"
    }
    
    if _, ok := s["x"]; ok {
    	// s has "x"
    }
    
  2. Unless you can guarantee that b does not have any false values, iterating over the elements is easier with s:

    for e, v := range b {
    	if v {
    		// e is an element of b
    	}
    }
    
    for e := range s {
    	// e is an element of s
    }
    
  3. s is more memory-efficient than b.

As an alternative, you can use an open-source library. For instance:

Of course, currently, it's not possible to implement generic sets in Go. But with the planned addition of generics to Go, it will be possible in a later version (no earlier than 1.17).

答案4

得分: 0

如果有人需要一个int的集合,可以使用以下代码:

package main
import "golang.org/x/tools/container/intsets"

func main() {
   var (
      a intsets.Sparse
      b bool
   )
   b = a.Insert(9)
   println(b) // true
   b = a.Insert(9)
   println(b) // false
}

https://pkg.go.dev/golang.org/x/tools/container/intsets

英文:

If anyone need a set of int, you can use this:

package main
import "golang.org/x/tools/container/intsets"

func main() {
   var (
      a intsets.Sparse
      b bool
   )
   b = a.Insert(9)
   println(b) // true
   b = a.Insert(9)
   println(b) // false
}

https://pkg.go.dev/golang.org/x/tools/container/intsets

huangapple
  • 本文由 发表于 2010年11月27日 12:45:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/4290171.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定