3week-4切片

一.切片的特性

  1. 可以切除来一个新的子片
  2. 长度可变,长度元素个数
  3. 容量可变,长度和容量可以不一样
  4. 底层用数组,(顺序表访问快)
  5. 推荐使用make定义,可以指定初始容量大小,减少频发扩容
  6. 切片复制的都是header,函数return的也是header,
    len控制各个共同使用底层数组的可见范围
    cap没有扩容之前还有几个位置可用
    首地址觉得容量还有多少,如果首地址偏移1,容量就会-1,偏移2,容量就会-2
  7. 判断切片是否是空 len(s) == 0 而不是用 s == nil

二.切片定义

//1.切片定义方式1---字面量定义

  • 适用于少了元素
var s0 = []int{1, 3, 5, 7, 9} //{}里面是字面量;字面量定义就是初始化的时候把元素写好了,长度为5,容量为5
fmt.Printf("s0的类型:%T  s0的值:%[1]v  s0的长度%d  s0的容量%d\n", s0, len(s0), cap(s0))

结果

2.声明空切片方式1---不常用

  • 空切片随时准备膨胀
  • %P输出内存地址,否则输出%v
var s1 []int //  仅是声明,零值填充,长度为0,容量为0
fmt.Println(s1, len(s1), cap(s1), &s1)
fmt.Printf("%p %[1]T", &s1)
fmt.Printf(" %p %[1]T", s1)

3.推导定义声明切片2---不常用

var s2 = []int{} //生成[]int切片,长度和容量都是0
fmt.Printf("s2的地址是:%p  s2的类型是:%[1]T\n", &s2)

结果:

4.make声明切片1

  • 用的多,推荐使用 make可以给内建容器开辟内存空间
  • 适用于很多个元素

切片的参数

var s3 = make([]string, 0) // 切片使用make,第二个参数0表示长度.为0的切片,没有元素容量也为0
fmt.Println(s3, len(s3), cap(s3))

结果

5.make定义切片2

1.切片参数

s4 := make([]string, 0, 5) //切片使用make,第2个参数0表示长度为0, 第三个参数表示容量为5
s4 := make([]string, 10) //如果只写了第一个参数,长度和容量相同都是10
fmt.Println(s4, len(s4), cap(s4))

6.先用make定义100个.然后初始化几个

三.切片内存模型

1.

  • append返回的就是header
  • 指针: 指向底层数组
  • 当前切片的元素个数
  • cap当前切片的容量,容量是能容纳多少元素不爆

2.数组撑爆问题


结果

四切片append

  • append函数的作用: 用于切片,对某切片追加元素,不会修改切片的header,返回值可以用的,返回值是新header,新header里面的指针可能变了,len,cap也有可能变了
  • 如果append追加到s0,把s0撑爆,会产生新的数组

1.append1---切片共享底层数组分析

func main() {
	var s0 = make([]int, 3, 5)                                                   //长度为3(用了3个元素),容量为5(空着2个元素;值=零)
	fmt.Printf("s0 :%p, %p, %-2d, %-2d,%v\n", &s0, &s0[0], len(s0), cap(s0), s0) //0xc000004078, 0xc00000a420, 3 , 5 ,[0 0 0]
	s1 := append(s0, 1, 2)                                                       //往s0里追加2个元素是1,2;由于s0长3,容量5,虽然增加了,但没有撑爆s0,append不更新s0的heder
	fmt.Printf("s0 :%p, %p, %-2d, %-2d,%v\n", &s0, &s0[0], len(s0), cap(s0), s0) //[0 0 0]
	fmt.Printf("s1 :%p, %p, %-2d, %-2d,%v\n", &s1, &s1[0], len(s1), cap(s1), s1) //[0 0 0 1 2]append追加不会更新s0的herder
	// fmt.Println(s0[2])
}
  • 结果:
  • 显示元素分析图

2.append2---切片共享底层数组分析

s0,s1,s2自己看自己的长度,看底层数组s0的容量;;如果长度撑爆底层数组,如果谁撑爆数组,就开辟

func main() {
  s2 := append(s0, -1)
  //1.因为s0[0 0 0],len(3) cap(5); append,向 s0 追加-1,没有撑爆s0,
  //2.那么不用新生成底层数组,使用s0底层数组进行追加,[0 0 0 -1]len4,cap5
  //3.append返回新header给s2;  s3的header指针指向s0
  fmt.Printf("s0 :%p, %p, %-2d, %-2d,%v\n", &s0, &s0[0], len(s0), cap(s0), s0) //s0=[0 0 0]      len=3 cap=5
  fmt.Printf("s1 :%p, %p, %-2d, %-2d,%v\n", &s1, &s1[0], len(s1), cap(s1), s1) //s1=[0 0 0 -1 2] len=5 cap=5
  fmt.Printf("s2 :%p, %p, %-2d, %-2d,%v\n", &s2, &s2[0], len(s2), cap(s2), s2) //s2=[0 0 0 -1]   len4, cap5
}
  • 结果
  • 显示元素分析图

3.append3---切片撑爆底层数字组分析

func main() {
  s2 := append(s0, -1)
    //1.因为s0[0 0 0],len(3) cap(5); append,向 s0 追加-1,没有撑爆s0,
    //2.那么不用新生成底层数组,使用s0底层数组进行追加,[0 0 0 -1]len4,cap5
    //3.append返回新header给s2;  s3的header指针指向s0
  fmt.Printf("s0 :%p, %p, %-2d, %-2d,%v\n", &s0, &s0[0], len(s0), cap(s0), s0) //s0=[0 0 0]      len=3 cap=5
  fmt.Printf("s1 :%p, %p, %-2d, %-2d,%v\n", &s1, &s1[0], len(s1), cap(s1), s1) //s1=[0 0 0 -1 2] len=5 cap=5
  fmt.Printf("s2 :%p, %p, %-2d, %-2d,%v\n", &s2, &s2[0], len(s2), cap(s2), s2) //s2=[0 0 0 -1]   len4, cap5
  fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~")

  s3 := append(s2, 3, 4, 5)
    //1.因为s2=[0 0 0 -1] len(4) cap(5); append向 s2 追加3,4,5; 撑爆了s2
    //2.那么生成新的底层数组,复制s2的元素到新数组,插入3,4,5;[0 0 0 -1 3 4 5]len7,cap10
    //3.append返回新heder给s3; s3指针指向新底层数组地址
  fmt.Printf("s0 :%p, %p, %-2d, %-2d,%v\n", &s0, &s0[0], len(s0), cap(s0), s0)   //s0=[0 0 0]      len=3 cap=5
  fmt.Printf("s1 :%p, %p, %-2d, %-2d,%v\n", &s1, &s1[0], len(s1), cap(s1), s1)   //s1=[0 0 0 -1 2] len=5 cap=5
  fmt.Printf("s2 :%p, %p, %-2d, %-2d,%v\n", &s2, &s2[0], len(s2), cap(s2), s2)   //s2=[0 0 0 -1]   len=4, cap=5
  fmt.Printf("s3 :%p, %p, %-2d, %-2d,%v\n", &s3, &s3[0], len(s3), cap(s3), s3)   //s3=[0 0 0 -1 3 4 5]  len=7 cap=10容量翻倍5X2=10
}
  • 结果

  • 显示元素分析

append,返回的header给底层数组分析

s3 = append(s3, 6, 7, 8, 9)
fmt.Printf("s3 :%p, %p, %-2d, %-2d,%v\n", &s3, &s3[0], len(s3), cap(s3), s3) //s3=[0 0 0 -1 3 4 5]  len=7 cap=10
  • 结果

  • 显示header地址分析,S3的地址没变,值变了

posted @ 2023-01-05 00:59  john5的博客  阅读(30)  评论(0)    收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css