Golang语法系列——slice切片和数组

slice切片底层

基于数组实现,可动态拓容,

切片拓容规则

append() 在分配内存空间之前需要先确定新的切片容量,运行时根据切片的当前容量选择不同的策略进行扩容

  • 如果期望容量大于当前容量的两倍就会使用期望容量;

  • 如果当前切片的长度小于 1024 就会将容量翻倍;

  • 如果当前切片的长度大于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量;


copy拷贝,runtime.memmove 能够提供更好的性能。需要注意的是,整块拷贝内存仍然会占用非常多的资源,在大切片上执行拷贝操作时一定要注意对性能的影响


总结

  1. append 注意拓容规则,初始化时可规划好长度
  2. copy 避免大切片拷贝

slice使用

slice cap分析

copy() 是值赋值,不会影响原切片cap,同时基于数组的新切片,修改新切片值,会覆盖数组的值。

  
  
  arr := [10]int64{1,2,3,4,5,6,7,8,9,10}
	s1 := arr[2:4:8] 	// cap=6,len=2 cap 针对源数组 arr 由2开始
	s2 := arr[2:4] 		// cap=8,len=2
  s3 := arrp[:4] 		// cap=10,len=4 
  //s1[0] = 4 // arr: [1,2,4,4,5,6,7,8,9,10] //切片指向arr地址,修改会覆盖
  //cp := []int64{22,33}
  //copy(s1,cp) //arr: [1,2,22,33,5,6,7,8,9,10] copy是值复制,不影响s1的cap
	
	fmt.Println(s1) //[3 4]
	fmt.Println(s2) //[3 4]
	fmt.Println(s1[:cap(s1)]) //[3 4 5 6 7 8]
	fmt.Println(cap(s1)) // 6 8-2
	fmt.Println(len(s1)) // 2
	fmt.Println(s2[:cap(s2)])//[3 4 5 6 7 8 9 10]
	fmt.Println(cap(s2)) // 8  10-2
	fmt.Println(len(s2)) // 2

  

Slice增加元素重新分配内存

slice在添加元素前,与其它切片共享同一数据区域,修改会相互影响;但添加元素导致内存重新分配之后,不再指向原来的数据区域,修改元素,不再影响其它切片。

    s1 := []int{1,2,3}
    fmt.Println(len(s1),cap(s1),s1) //prints 3 3 [1 2 3]

    s2 := s1[1:]
    fmt.Println(len(s2),cap(s2),s2) //prints 2 2 [2 3]

    for i := range s2 { s2[i] += 20 }

    //still referencing the same array
    fmt.Println(s1) //prints [1 22 23]
    fmt.Println(s2) //prints [22 23]

    s2 = append(s2,4)

    for i := range s2 { s2[i] += 10 }

    //s1 is now "stale"
    fmt.Println(s1) //prints [1 22 23]
    fmt.Println(s2) //prints [32 33 14]

参考链接

Golang中,有几种初始化切片的方式可以使用。 第一种方式是使用字面量来初始化切片。这种方式会创建一个匿名的底层数组,并将切片指向数组的第一个元素。例如,可以使用以下语法来初始化一个切片: s := []int{1,2,3} 这将创建一个整型切片s,其中包含了元素1、2和3。 第二种方式是基于已经存在的数组来初始化切片。可以通过指定切片的下界和上界来限定切片能访问数组的范围。例如,可以使用以下语法来初始化一个切片: a := [5]int{1,2,3,4,5} s := a[:] 或者可以使用以下语法来初始化一个切片: s := []int{1,2,3,4,5} s2 := s<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Golang切片的声明、初始化以及操作示例,详解、概括](https://blog.csdn.net/qq_25805331/article/details/120306433)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【GolangSlice](https://blog.csdn.net/dai815904261/article/details/124046351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值