一尘不染

为什么Go中不经常使用列表?

go

我是Go的新手,对此感到很兴奋。但是,在我广泛使用的所有语言中:Delphi,C#,C ++,Python-
列表非常重要,因为列表可以动态调整大小,而不是数组。

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

看来,与Python不同,RangeList不支持Python,这是IMO的一大缺陷。我想念什么吗?

切片当然不错,但是它们仍然需要基于具有硬编码大小的数组。这就是List出现的地方。有没有一种方法可以在Go中创建数组/切片,而无需使用硬编码的数组大小?为什么列表被忽略?


阅读 291

收藏
2020-07-02

共1个答案

一尘不染

几个月前,当我第一次开始研究Go时,我问了这个问题。从那时起,我每天都在阅读有关Go的内容,并在Go中进行编码。

因为我没有收到关于该问题的明确答案(尽管我已经接受了一个答案),所以我现在要根据我所学到的内容自行回答,因为我已经问过:

有没有一种方法可以在没有硬编码数组大小的情况下在Go中创建数组/切片?

是。切片不需要硬编码数组即可slice从:

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

此代码分配slice sl,其大小lencap-,len并且cap是可以在运行时分配的变量。

为什么被list.List忽略?

list.List似乎在Go中很少引起注意的主要原因是:

  • 正如@Nick Craig-Wood的答案中所解释的那样,对于列表而言,用切片无法完成的事情几乎是无法完成的,通常更有效,更简洁,更优雅的语法也无法做到。例如范围构造:
    for i:=range sl {
    

    sl[i]=i
    }

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

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

我放弃Python并转而使用Go的原因之一是由于Python的类型系统中的这种弱点,尽​​管Python声称自己是“强类型”(IMO并非如此)。Go
list.List似乎是一种“杂种”,由C ++ vector<T>和Python产生 List(),并且在Go本身中可能有点不合适。

如果在不远的将来的某个时刻找到list,这并不令我感到惊讶。在Go中不推荐使用list,尽管它可能会保留,以适应那些 罕见的
情况,即使使用良好的设计实践,也可以最好地解决问题与拥有各种类型的集合。或者,它可以为C系列开发人员提供一个“桥梁”,让他们在了解切片的细微差别之前熟悉Go,这对于AFAIK来说是Go特有的。(在某些方面,切片似乎与C
++或Delphi中的流类相似,但不完全相同。)

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

2020-07-02