An array is a contiguous piece of memory. slice is a structure with three fields: 长度 len , 容量 cap , 底层数组 .

 // runtime/slice.go
type slice struct {
    array unsafe.Pointer // 元素指针
    len   int // 长度 
    cap   int // 容量
}

slice的生命周期围绕着按cap预先底层数组cap cap*2底层数组 .

特别要注意的时,当我们使用---9c92618427e61ebcb4f47f15158f6ad8 下标范围子切片时, 子切片 父切片 底层数组 at this point it is 同一片内存地址 . Subsequent 子切片 may re-apply for capacity due to insufficient 容量cap , from 父切片 底层数组 from ---18ec920fe4dbffe.

 package main

import (
    "fmt"
)

func main() {
    slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    s1 := slice[2:5] //len3 cap8
    s2 := s1[2:6:7]  //len4 cap5

    fmt.Println(s1, len(s1), cap(s1))
    fmt.Println(s2, len(s2), cap(s2))
    fmt.Println(strings.Repeat("=", 10))

    //s2的容量已满 如果后续再追加成员,将重新分配一套底层数组
    s2 = append(s2, 100)
    //s1和s2还在公用一套底层数组 s1[2] == s2[0]
    s1[2] = 20
    fmt.Println(s1, len(s1), cap(s1))
    fmt.Println(s2, len(s2), cap(s2))
    fmt.Println(strings.Repeat("=", 10))

    //s2的重新分配底层数组 容量扩充为原来的2倍=5*2
    s2 = append(s2, 200)
    //s1与s2的底层数组已不同 s1[2] 已无法影响 s2[0]
    s1[2] = 200
    fmt.Println(s1, len(s1), cap(s1))
    fmt.Println(s2, len(s2), cap(s2))
}

Only when the sub-slice 容量cap is insufficient and re-applies to allocate a new capacity memory segment, it will be independently checked from the underlying array of the parent slice.


big_cat
1.7k 声望130 粉丝

规范至上