【问题标题】:Set of structs in GoGo 中的结构集
【发布时间】:2016-01-14 10:00:38
【问题描述】:

如果我有许多想要存储的结构:

type Stuff struct {
    a string
    b string
}

我可以使用切片来完成,但使用正确的集合结构似乎会使用更少的内存。

不幸的是,Go 没有固定的结构。每个人都建议使用map[Stuff]struct{},但这不起作用,因为Stuff 是一个结构。有人有什么好的解决方案吗?理想情况下无需下载库。

【问题讨论】:

标签: struct go set


【解决方案1】:

通常 set 和 map 数据结构需要比在普通数组或切片中存储值列表更多的内存,因为 set 和 map 有效地提供了其他功能,例如唯一性或按键检索值。

如果您想要最少的内存使用,只需将它们存储在一个切片中,例如[]Stuff。如果您在多个地方使用这些值,那么仅存储它们的指针也可能是有利可图的,例如[]*Stuff 等每个存储相同Stuff 值的地方都可以存储相同的指针(不重复值)。

如果您只想存储唯一的结构值,那么 set 确实是最方便的选择,在 Go 中使用 map 实现。

map[Stuff]struct{} 没有问题,它可以工作。地图的requirement for the key type

comparison operators == 和 != 必须为键类型的操作数完全定义;因此键类型不能是函数、映射或切片。

Stuff 是一个结构体,structs in Go are comparable 如果:

如果结构值的所有字段都是可比较的,则结构值是可比较的。如果对应的非blank 字段相等,则两个结构值相等。

如果您的 Stuff 结构是您发布的,那么它是可比较的:它只包含可比较类型的字段 string

还要注意,如果你想要一个集合的数据结构,如果你使用bool作为值类型(例如map[Stuff]bool)和true作为值,那么你可以简单地使用indexing来测试一个值是否在映射中,因为如果键(在您的情况下为Stuff)不在映射中,则索引表达式产生值类型的零值(false for bool),正确地告诉值您要查找的内容不在“集合”中。 (如果它在地图中,则其关联的true 值是索引表达式的结果 - 正确地告诉它在地图中)。

【讨论】:

  • 啊,谢谢,我猜是因为我的真实代码中的某些字段没有可比性。
  • 另外值得注意的是,如果你有一个巨大的集合并且对内存造成伤害,你可以使用map[Stuff]struct{}而不是bool来节省一点内存,并使用if _, ok := m[Stuff{"a", "b"}]; ok { .... }进行检查
猜你喜欢
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 2013-08-07
  • 2017-07-27
  • 1970-01-01
  • 2012-11-25
  • 2011-10-04
  • 1970-01-01
相关资源
最近更新 更多