golang 切片原理面试题

package main

import "fmt"

func main() {
	var s = make([]int, 0, 10)
	_ = append(s, 1,2,3)
	fmt.Println(s)
	fmt.Println(s[0:cap(s)])
}

第一次打印和第二次打印分别是什么值了?
第一次打印:[]
第二次打印:[1 2 3 0 0 0 0 0 0 0]

原因: 当append返回的新切片不需要赋值回原有的变量时, 源代码此时执行如下:

ptr, len, cap := slice
newlen := len + 3
if newlen > cap {
    ptr, len, cap = growslice(slice, newlen)
    newlen = len + 3
}
*(ptr+len) = 1
*(ptr+len+1) = 2
*(ptr+len+2) = 3
return makeslice(ptr, newlen, cap)

很明显s的长度加上3之后此时还是不会扩容。所以切片引用的还是原数组。
但是第一次打印的s因为len还是0,所以此时自然打印出[]。
而第二次打印的s因为字面量创建,此时的长度变为了10,就自然打印出了整个原数组了。

本文参考资料:

  1. https://zhuanlan.zhihu.com/p/29753411
  2. https://draveness.me/golang/docs/part2-foundation/ch03-datastructure/golang-array-and-slice/#324-追加和扩容

posted on 2022-03-22 15:40  biwentao  阅读(141)  评论(0编辑  收藏  举报

导航