切片底层数组详解

package main

import "fmt"

func main() {
    s := []int{0,1,2,3,4,5,6,7,8,9}
    s1 := s[1:5]
    fmt.Printf("s[1] ==> %p,s长度==> %d,s容量==>%d \n",&s[1],len(s),cap(s))
    fmt.Printf("s[2] ==> %p \n",&s[2])
    fmt.Printf("s[3] ==> %p \n",&s[3])
    fmt.Printf("s[4] ==> %p \n",&s[4])
    fmt.Printf("s[5] ==> %p \n",&s[5])
    fmt.Printf("s[6] ==> %p \n",&s[9])
    fmt.Println("--------------------------------------")
    fmt.Printf("s1[0] ==> %p ,s1长度==> %d,s1容量==>%d \n",&s1[0],len(s1),cap(s1))
    fmt.Printf("s1[1] ==> %p \n",&s1[1])
    fmt.Printf("s1[2] ==> %p \n",&s1[2])
    fmt.Printf("s1[3] ==> %p \n",&s1[3])
    fmt.Println("--------------------------------------")
    s2 := append(s1,10)
    fmt.Printf("s2[0] ==> %p s2长度==> %d,s2容量==>%d \n",&s2[0],len(s2),cap(s2))
    fmt.Printf("s2[4] ==> %p \n",&s2[4])
    fmt.Println("--------------------------------------")
    s3 := append(s2,[]int{11,12,13,14,15}...)
    fmt.Printf("s3[0] == > %p s3长度==> %d,s3容量==>%d \n",&s3[0],len(s3),cap(s3))
    fmt.Println(s3)
}
s[1] ==> 0xc000014198,s长度==> 10,s容量==>10
s[2] ==> 0xc0000141a0
s[3] ==> 0xc0000141a8
s[4] ==> 0xc0000141b0
s[5] ==> 0xc0000141b8
s[6] ==> 0xc0000141d8
--------------------------------------
s1[0] ==> 0xc000014198 ,s1长度==> 4,s1容量==>9
s1[1] ==> 0xc0000141a0
s1[2] ==> 0xc0000141a8
s1[3] ==> 0xc0000141b0
--------------------------------------
s2[0] ==> 0xc000014198 s2长度==> 5,s2容量==>9
s2[4] ==> 0xc0000141b8
--------------------------------------
s3[0] == > 0xc000016090 s3长度==> 10,s3容量==>18
[1 2 3 4 10 11 12 13 14 15]

1.s1 := s[1:5],这是s1的长度为 4 ,容量就是 s从 1 开始后面的容量,当我们打印 s1s的前几个元素指针的时候发现s1的四个元素的指针正好是s的 第一号到第四号,可以证明 s1s公用一个底层数组。

2.这时候我们往s1里添加一个元素,再打印元素的指针,发现s2的第四号元素地址正好和 s1的第五号元素地址相同,这证明s2和前两个切片还是共用底层数组。

3.我们往s2添加五个元素,s2本来的长度是 5 ,容量是 9 ,这时候添加五个元素会导致自动扩容,这时候再打印s3的元素地址,发现与前三个切片的元素地址不同,说明扩容后已经重新分配了内存地址。自动扩容的容量计算在上一篇。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

发现你的电脑是64位系统 :smiley:

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!