为什么在 Go 中很少使用列表?

新手上路,请多包涵

有没有办法在没有硬编码数组大小的情况下在 Go 中创建数组/切片?为什么列表被忽略?

在我广泛使用的所有语言中:Delphi、C#、C++、Python - 列表非常重要,因为它们可以动态调整大小,而不是数组。

在 Golang 中,确实有一个 list.List 结构,但我看不到关于它的文档——无论是在 Go By Example 还是我拥有的三本 Go 书籍——Summerfield、Chisnal 和 Balbaert——他们都花了很多钱数组和切片上的时间,然后跳到映射。在源代码示例中,我也发现很少或根本没有使用 list.List

看来,与 Python 不同, Range 不支持列表 - IMO 的一大缺点。我错过了什么吗?

切片很可爱,但它们仍然需要基于具有硬编码大小的数组。这就是 List 的用武之地。

原文由 Vector 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 703
2 个回答

几个月前,当我第一次开始研究 Go 时,我问过这个问题。从那以后,我每天都在阅读有关 Go 的文章,并用 Go 编写代码。

因为我没有得到这个问题的明确答案(虽然我已经接受了一个答案)所以我现在根据我所学的知识自己回答它:

有没有办法在没有硬编码数组大小的情况下在 Go 中创建数组/切片?

是的。切片不需要硬编码数组 slice 来自:

 var sl []int = make([]int, len, cap)

This code allocates slice sl , of size len with a capacity of cap - len and cap are variables可以在运行时分配。

为什么 list.List 被忽略了?

看起来主要原因 list.List 在 Go 中似乎很少受到关注是:

  • 正如@Nick Craig-Wood 的回答中所解释的那样,几乎没有什么可以用列表来完成而不能用切片来完成,通常更有效并且使用更清晰,更优雅的语法。例如范围构造:
    for i := range sl {
     sl[i] = i
   }

不能与列表一起使用 - 需要 C 风格的 for 循环。在许多情况下,C++ 集合样式语法必须与列表一起使用: push_back 等。

  • 也许更重要的是, list.List 不是强类型的——它与 Python 的列表和字典非常相似,它们允许在集合中将各种类型混合在一起。这似乎与 Go 的处理方法背道而驰。 Go 是一种非常强类型的语言——例如,Go 中不允许隐式类型转换,即使是从 intint64 的 upCast 也必须是显式的。但是 list.List 的所有方法都采用空接口 - 任何事情都可以。

我放弃 Python 并转向 Go 的原因之一是因为 Python 类型系统的这种弱点,尽管 Python 声称是“强类型”(IMO 不是)。 Go的 list.List 似乎是一种“杂种”,诞生于C++的 vector<T> 和Python的 List() 本身

如果在不久的将来的某个时候,我们发现 list.List 在 Go 中被弃用,我不会感到惊讶,尽管它可能会保留下来,以适应那些即使使用良好的设计实践,也可以最好地解决问题的 罕见 情况有一个包含各种类型的集合。或者它可能是为 C 系列开发人员提供一个“桥梁”,让他们在学习 slice 的细微差别之前熟悉 Go,这是 Go 所独有的,AFAIK。 (在某些方面,切片看起来类似于 C++ 或 Delphi 中的流类,但不完全是。)

尽管来自 Delphi/C++/Python 背景,但在我最初接触 Go 时,我发现 list.List 比 Go 的切片更熟悉,因为我对 Go 越来越熟悉,所以我回过头来改变了所有我的列表切片。我还没有发现任何东西 slice 和/或 map 不允许我这样做,所以我需要使用 list.List

原文由 Vector 发布,翻译遵循 CC BY-SA 4.0 许可协议

当你想到列表时几乎总是 - 在 Go 中使用切片代替。切片动态调整大小。它们的底层是可以改变大小的连续内存片。

它们非常灵活,如果您阅读 SliceTricks wiki 页面,就会看到这一点。

这是摘录:-

复制

b = make([]T, len(a))
copy(b, a) // or b = append([]T(nil), a...)

a = append(a[:i], a[j:]...)

删除

a = append(a[:i], a[i+1:]...) // or a = a[:i+copy(a[i:], a[i+1:])]

删除而不保留顺序

a[i], a = a[len(a)-1], a[:len(a)-1]

流行音乐

x, a = a[len(a)-1], a[:len(a)-1]

a = append(a, x)

更新:这是一个链接,指向来自 go 团队本身 的所有关于切片的博客文章,它很好地解释了切片和数组以及切片内部结构之间的关系。

原文由 Nick Craig-Wood 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题