Data structures 戈朗为什么不';我们没有一套数据结构吗

Data structures 戈朗为什么不';我们没有一套数据结构吗,data-structures,go,set,Data Structures,Go,Set,我正在尝试解决“go programming lanaguage”练习#1.4,这要求我有一套。我可以创建一个集合类型,但是为什么该语言不附带一个呢?go,来自谷歌,guava也是谷歌的发源地,为什么语言设计师不选择添加对基本数据结构的支持?为什么要强迫用户为一个集合这样基本的东西创建他们自己的实现呢?部分原因是Go没有泛型(因此每个类型都需要一个集合类型,或者依赖反射,这是相当低效的) 部分原因是,如果您只需要“向集合中添加/删除单个元素”和“相对节省空间”,那么只需使用map[yourtyp

我正在尝试解决“go programming lanaguage”练习#1.4,这要求我有一套。我可以创建一个集合类型,但是为什么该语言不附带一个呢?go,来自谷歌,guava也是谷歌的发源地,为什么语言设计师不选择添加对基本数据结构的支持?为什么要强迫用户为一个集合这样基本的东西创建他们自己的实现呢?

部分原因是Go没有泛型(因此每个类型都需要一个集合类型,或者依赖反射,这是相当低效的)


部分原因是,如果您只需要“向集合中添加/删除单个元素”和“相对节省空间”,那么只需使用
map[yourtype]bool
(并将集合中的任何元素的值设置为
true
),或者为了更节省空间,您可以使用空结构作为值并使用
,present=检查是否存在的setoid[键]

一个原因是从地图创建集合很容易:

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_intersection := map[int]bool{}
if len(s1) > len(s2) {
  s1, s2 = s2, s1 // better to iterate over a shorter set
}
for k,_ := range s1 { 
  if s2[k] {
    s_intersection[k] = true
  }
}

实现所有其他集合操作其实并不难。

就像Vatine所写的:由于go缺少泛型,它必须是语言的一部分,而不是标准库。因此,您将不得不用关键字set、union、intersection、difference、subset污染语言

另一个原因是,根本不清楚set的“正确”实现是什么:

  • 有一种功能性方法:

    func IsInEvenNumbers(n int) bool {
        if n % 2 == 0 {
            return true
        }
       return false
    }
    
  • 这是一组所有偶数整数。它有一个非常有效的查找和并集,交集,差异和子集可以很容易地通过功能组合

  • 或者你用达利展示的方法


  • 映射没有这个问题,因为您存储了与值相关的内容。

    另一种可能是使用位集,至少有一个位集,或者您可以使用内置包。在这种情况下,基本上您需要定义一种将对象转换为索引的方法。

    检查是否存在只是为地图编制索引。因为如果它不在里面,零值(它是
    false
    )会正确地告诉你。测试不需要逗号ok习惯用法。交叉点的实现类似于差异的实现。使用
    map[int]struct{}
    而不是
    bool
    ,因为空结构在内存中占用0字节。我最近为此写了一个要点,但不是很容易。在我看来,现在只要在需要使用集合的任何地方编写代码都是荒谬的。集合支持应该由任何语言提供。我认为更好的答案是围棋还没有成熟。我相信很快就会有图书馆来涵盖这一点。这既不容易,也不直观。这不是一个集合,它只是一个行为类似集合的代码模式。它不是一个集合,因为它不存储数据,也不像集合那样提供操作。正确的答案是GO没有这个功能。有办法做某件事并不意味着它是不拥有它的理由。为了处理内置集,Pascal重载了一组二进制(两个参数)运算符:
    +
    表示联合,
    -
    表示差异,
    *
    表示交叉,
    =
    表示超集,
    =
    表示相等,
    表示不平等,而
    中的
    表示成员资格。所以在Go中,它将只是一个新的关键字--
    中的
    。另一方面,Pascal的内置集只对“序数”起作用——即任何具有某种大小的整数值的底层表示形式的类型。实现一个集有多种方法的事实并没有阻止许多其他语言提供它们。@kostix:Go甚至可以使用语法
    s[key]
    (好像
    s
    是一个
    map[T]bool
    )代替
    输入s
    。有没有理由不简单地返回
    n%2==0
    ?我知道这已经5年了,但是
    用关键字set、union、intersection、difference、subset
    污染了语言,真的吗?除了
    set
    之外,其余的都是对set的操作,所以它们都是函数。我应该注意,我写了最初的ve上面提到的位集包的rsion。另外,Go的精神似乎是在自己的代码中写出来,或者通过“内联”其他代码中的集合,或者在需要时定义自己的集合类型。无论如何,使用STD::C++中的设置总是作为函数实现的一部分或实现其他数据结构。因此,只需使用映射和切片以及其他需要的构建块,实现其他数据结构,但不需要。任何内置集合。集合的每次使用都会略有不同:)但通常你并不真正需要集合本身,你使用集合作为实现更大功能的一部分。我已经看过很多代码,其中为了包含一个“可重用”组件而需要做的事情比仅仅避免需要要糟糕得多。这里我们有一个集合,那边的函数需要一个集合,哦,我们有协方差吗,或者制作一个包装工厂使它看起来像这个东西,等等。也许另一个函数真的需要一个可以检查成员身份的接口,所以不要发送集合。所以如果它没有泛型,“通用”映射是如何实现的?请注意,如果您想保存字节,可以使用
    map[T]struct{}
    而不是
    map[T]bool
    。看看hmmm。想知道为什么会有反对票?我来自java世界,我们几乎从一开始就有一个集合,即使没有泛型。所以,我觉得这种行为有点奇怪
    func IsInEvenNumbers(n int) bool {
        if n % 2 == 0 {
            return true
        }
       return false
    }