写点什么

Golang Array and Slice

用户头像
escray
关注
发布于: 2021 年 05 月 17 日
Golang Array and Slice

极客时间《Go 语言核心 36 讲》学习笔记 06,图片来自网络

07 | 数组和切片


留言人数创新高,看来很多同学都和我一样对数组 array 和 切片 slice 有兴趣,其实本篇主要讲的是切片,当然数组是切片的基础。


面试的时候,随便问一下数组和切片,就可以聊的风生水起了。


An array is a numbered sequence of elements of a single type... Array types are always one-dimensional but may be composed to form multi-dimensional types.


A slice is a descriptor for a contiguous segment of an underlying array and provides access to a numbered sequence of elements from that array.


数组和切片都属于集合类的类型,都有 len 和 cap 方法,那么时候可以用统一的方式打印出来呢?类似于


fmt.Printf("len: %d, cap: %d\n", len(slice), cap(slice))
复制代码


每个切片的底层数据结构中,一定包含一个数组,切片的容量可以看做是透过这个窗口最多可以看到的底层数组中元素的个数。


老师的“窗口”说,实在是太形象了,特别是


s4[0:cap(s4)+1]
复制代码


会在运行时报错:


panic: runtime error: slice bounds out of range [:6] with capacity 5
复制代码


抄一段 growslice 中的代码


newcap := old.capdoublecap := newcap + newcapif cap > doublecap {    newcap = cap} else {    if old.len < 1024 {        newcap = doublecap    } else {        // Check 0 < newcap to detect overflow        // and prevent an infinite loop.        for 0 < newcap && newcap < cap {            newcap += newcap / 4        }        // Set newcap to the requested cap when        // the newcap calculation overflowed.        if newcap <= 0 {            newcap = cap        }    }}
复制代码


append 函数返回的是原底层数组的原切片还是新底层数组的新切片,也很 tricky


对于思考题:


  1. 如果有多个切片指向同一个底层数组,那么应该要小心不要被“别人”的修改影响

  2. 照猫画虎的缩容代码


newcap := old.caphalfcap := old.cap / 2
if cap < halfcap { newcap := cap} else { if old.len < 1024 { newcap = halfcap } else { for 0 < newcap && newcap < cap { newcap -= newcap / 5 } if newcap <= 0 { newcap = cap } }}
复制代码


slice.go 的源码中没有提供缩容代码,按照留言中的提示,缩容会引用底层的原始数组,影响垃圾回收,不如新建数组,然后 copy。


另外看到留言里面有同学“暴力”缩容,估计效果不错


func shrinkSlice(x []int) []int{    if( cap(x) > 0 ) {        x = x[0:cap(x)-1]    }    return x}
复制代码


看了置顶的两条评论,其实有一个根本的问题就是:是老师适应学生,还是学生适应老师。我觉得在学习阶段,应该还是学生更主动一些。即使是同事之间的探讨,可能也需要去适应对方的说话风格和习惯,而不是希望对方改变。

发布于: 2021 年 05 月 17 日阅读数: 11
用户头像

escray

关注

Let's Go 2017.11.19 加入

Let's Go,用 100 天的时间从入门到入职

评论

发布
暂无评论
Golang Array and Slice