Answers:
在某种程度上,因为Go没有泛型(因此您需要为每个类型使用一个set-type,否则将依靠反射,这是相当低效的)。
部分地,因为如果您需要的只是“将单个元素添加/删除到集合中”和“相对节省空间”,则只需使用map[yourtype]bool
(就true
可以将集合中任何元素的值设置为),或者为了提高空间效率,您可以使用空结构作为值并用于_, present = the_setoid[key]
检查是否存在。
map[T]struct{}
代替map[T]bool
。
一个原因是从地图创建集合很容易:
s := map[int]bool{5: true, 2: true}
_, ok := s[6] // check for existence
s[8] = true // add element
delete(s, 2) // remove element
联盟
s_union := map[int]bool{}
for k, _ := range s1{
s_union[k] = true
}
for k, _ := range s2{
s_union[k] = true
}
路口
s_intersection := map[int]bool{}
for k,_ := range s1 {
if s2[k] {
s_intersection[k] = true
}
}
实施所有其他设置操作并不难。
false
)将正确地表明这一点。无需逗号习惯用法即可进行测试。
map[int]struct{}
代替bool
,因为空结构在内存中占用0字节。我最近为此gist.github.com/bgadrian/cb8b9344d9c66571ef331a14eb7a2e80
就像Vatine写道:由于go缺少泛型,因此它必须是语言的一部分,而不是标准库。为此,您将不得不用关键字set,union,intersection,difference,subset来污染语言。
另一个原因是,完全不清楚集合的“正确”实现是什么:
有一种实用的方法:
func IsInEvenNumbers(n int) bool {
if n % 2 == 0 {
return true
}
return false
}
这是所有偶数的集合。它具有非常高效的查找功能,并且可以通过功能组合轻松地实现并集,相交,差异和子集。
映射不存在该问题,因为您存储了与值关联的内容。
+
对于并集,-
差,*
交集,<=
子集,>=
超集,=
等式,<>
不等式和in
隶属度。因此,在Go中,它只是一个新关键字- in
。另一方面,Pascal的内置设置仅适用于“序数”,即具有基本大小表示形式的整数的任何类型。
s[key]
(好像s
是map[T]bool
)代替key in s
。
n % 2 == 0
?