Array

  • 数组是值,赋值、传参时会复制

  • 数组不需要显式的初始化操作

  1. var a [4]int
  2. a[2] == 0
  • 在内存中分配一块连续的内存,在内存中布局:

Slice - 图1

Slice

make

  • 定义如下:
  1. func make([]T, len, cap) []T
  • cap 是切片的初始容量,cap 是可选参数,如果省略,默认为 len。
  1. s := make([]byte, 5)
  2. len(s) == 5
  3. cap(s) == 5
  • cap 不可以小于 len,否则会有编译错误
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. defer func() {
  7. if err := recover(); err != nil {
  8. fmt.Printf("Recover from error: %v", err)
  9. }
  10. }()
  11. s := make([]int, 5, 4)
  12. fmt.Printf("len = %d, cap = %d", len(s), cap(s))
  13. }
  14. // prog.go:13:11: len larger than cap in make([]int)

内部结构

image.png
上图中,ptr是指向array的pointer,len是指切片的长度, cap指的是切片的容量。
这里为什么 cap 变成 3 了呢?

  1. s := x[2:4]
  2. len(s) == 2
  3. cap(s) == 3
  • Growing
  1. t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
  2. for i := range s {
  3. t[i] = s[i]
  4. }
  5. s = t
  • 通过 copy 实现一个通用的追加操作
  1. func AppendByte(slice []byte, data ...byte) []byte {
  2. m := len(slice)
  3. n := m + len(data)
  4. if n > cap(slice) { // if necessary, reallocate
  5. // allocate double what's needed, for future growth.
  6. newSlice := make([]byte, (n+1)*2)
  7. copy(newSlice, slice)
  8. slice = newSlice
  9. }
  10. slice = slice[0:n]
  11. copy(slice[m:n], data)
  12. return slice
  13. }
  • 与函数配合使用
  1. func Filter(s []int, fn func(int) bool) []int {
  2. var p []int // == nil
  3. for _, v := range s {
  4. if fn(v) {
  5. p = append(p, v)
  6. }
  7. }
  8. return p
  9. }
  • append 方法
  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. s := []int{}
  7. fmt.Println(len(s), cap(s))
  8. for i := 0; i < 8; i++ {
  9. s = append(s, i)
  10. fmt.Println(len(s), cap(s))
  11. }
  12. }
  13. // 0 0
  14. // 1 2
  15. // 2 2
  16. // 3 4
  17. // 4 4
  18. // 5 8
  19. // 6 8
  20. // 7 8
  21. // 8 8

nil

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var s []int = nil
  7. fmt.Println(len(s))
  8. s = append(s, 1)
  9. fmt.Println(len(s))
  10. }
  11. // 0
  12. // 1