golang 有 array 为啥要 slice

2022-02-13 18:46:25 +08:00
 GGGG430

如题, slice 相比于 array 的优势是什么, 平时还真没想过, 网上搜了一下, 感觉是长度可变这个优势 ? 各位大佬有了解的吗

3188 次点击
所在节点    Go 编程语言
14 条回复
Mitt
2022-02-13 18:59:44 +08:00
定长数组和变长数组的行为也不一样 不可互相替代的
cmdOptionKana
2022-02-13 19:48:58 +08:00
slice 底层就是用 array 实现的,只是包裹了很薄的一层而已,目的就是为了更方便地使用 array 。

换个角度讲,假设官方没有提供 slice ,你自己也必然会做一个类似的东西出来。由于可以预料几乎每个人在使用 array 时都会包裹一层,加些自动变长的方法,那官方直接提供一个类型就很合理了。
Hanggi
2022-02-13 20:20:35 +08:00
https://go.dev/tour/moretypes/8

看一下官方教程就可以知道,Slice 并不会存储任何数据。而是指向他底层的一个 array ,当你修改 slice 的数据实际上是在修改底层的 array 。

还有就是可以发现 Go 语言中没有 push 反而用 append 来添加元素。

https://go.dev/tour/moretypes/15

官方教程中也涉及到了,如果你增加元素到超过了底层的 array 的长度,他就会给你重新分配一个新的 array 来满足需求。

Go 语言教程做的还是很不错的,有空可以多看看。
billzhuang
2022-02-13 21:00:56 +08:00
我记得 rust 也是类似的原因
fengjianxinghun
2022-02-13 21:10:07 +08:00
@cmdOptionKana 想多了,先前没有泛型你是包裹不出一个类型安全的 slice 的,官方的 slice 是编译器开后门。
Building
2022-02-13 21:11:34 +08:00
难道不是为了实现 Array 的 cow 机制吗?
Yother
2022-02-13 21:11:42 +08:00
为了性能。
ThanksSirAlex
2022-02-13 21:22:30 +08:00
就是包装了一个可变长度的数组,实际运用中固定长度的数组可用性太差
BeautifulSoap
2022-02-13 21:51:14 +08:00
就是为了可变长度啊,array 的长度是固定且不可变的,你创建 array 的时候必须明确指定这个 array 的长度,而实际开发时是很难预先知道要存入的数据到底多长的。难道为了能预留够长度直接创建个需求中可能来的最大长度(比如 32768 之类的)的数组吗(当然,在 c 语言中这是基操,勿惊)

还有,golang 的 slice 实际上就是对等于 c++中的 vector ,两者原理是一模一样的都是基于 array 的抽象数据结构

lz 看了上面官方的说明之后如果有兴趣继续了解的话,可以来看邓俊辉老师的《数据结构》公开课,第二章的向量就是讲的 c++的 vector ,和 go 的 slice 是完全相通的,甚至里面还详细告诉你为什么每次 go 的 slice 的扩容策略是 cap 翻倍之类的

https://www.xuetangx.com/course/THU08091000384/1391601
yulon
2022-02-13 21:55:32 +08:00
@BeautifulSoap 准确来说是 span ,vector 没有办法引用 array ,只是 Go 有 GC 所以可以延长生命周期
jim9606
2022-02-13 22:00:18 +08:00
对于只读或进行原地修改的数组参数的 func ,使用 slice 可以免去需要传三个参数(*arr,pos,len)的麻烦。
golang 中 array 的长度是类型的一部分,对于希望接收不定长函数的 func ,只能用 slice 。
laravel
2022-02-14 04:28:39 +08:00
dynamic array
fgwmlhdkkkw
2022-02-14 10:33:39 +08:00
你不用不就完事了……
GGGG430
2022-02-14 10:54:28 +08:00
@BeautifulSoap #9 感谢回答, 只有你的回答靠谱点; 不过还是要纠正一下最后的扩容策略, 有三种可能, 即 doublecap, newcap, 1.25 倍循环三种, 最后还会内存对齐

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/833583

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX