不会!
明确一点,Go 中切片的底层其实是数组,而数组本质就是一种地址分布连续的数据结构,如果地址不连续的则不能叫数组。可能是其他的结构,比如链表或映射
切片中主要包含三个信息,切片的开始位置(数组的地址),切片大小以及底层数组容量。正因为切片的底层结构是数组,所以就可以直接基于数组创建切片,比如:
a := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
s := a[1:6]
此时的切片结构是这样的,图示如下:
访问切片 s[0] 其实就是访问的 a[1] 位置,其实可以改变一下 s[0] 的值,就会发现 a[1] 的值也跟着改变了。
s[0] = 10
fmt.Println(a[1])
输出的结果是 10。
切片的长度和底层结构的容量分别可以通过 len 和 cap 获得。
fmt.Println(len(s)) // 6
fmt.Println(cap(s)) // 8
如果底层结构的数组容量不够了,Go 会自动帮助创建新的数组,并将 s 指向新创建的数组,基本是按需要的 2 倍容量申请,当然这个说法并不完成准确。具体情况如何,可以通过如下代码测试下,当容量较大时,扩容会按 2 的次方扩展。
for i := 0; i < 10; i++ {
fmt.Println(cap(s))
s = append(s, s...)
}
当然底层的这个数组是可以拿到的,但比较复杂,需要依赖反射操作。
最后再说一点,不连续的数据结构 Go 中通过第三方 container 的包提供。文档地址:
主要是 list 双向链表 和 ring 回环链表两种数据结构。
Directory /src/container
Name Synopsis
..
heap Package heap provides heap operations for any type that implements heap.Interface.
list Package list implements a doubly linked list.
ring Package ring implements operations on circular lists.
欢迎关注我的专栏,Golang 之旅,见证我的 Golang 学习历程。