Go slice(切片)的几个坑

2020-02-29  本文已影响0人  firebook

最近做的项目用的语言是Go,写代码的过程无可避免就要使用到slice,因为是从Java转过来的,对于我来说,slice就是Java的ArrayList。
晚上读《Go语言实战》,对照写代码过程碰到的问题,发现slice有一些隐蔽的坑,记录一下,权当备忘。

slice是当作动态数组来使用,底层用的是数组,内部实现有3个field:

  1. 指向数组第一个元素的指针
  2. 切片长度(已有元素长度)
  3. 切片容量(最多能够容纳多少元素)

第一个坑:子切片和父切片用的是同一个底层数组

看代码:

pSlice := []int{0, 10, 20, 30, 40}
//新建一个子切片,指定元素为pSlice的index 1到3(不包括3),即{10, 20}
subSlice := pSlice[1:3] 

这时候,改变subSlice的值,也会改动到pSlice

subSlice[1] = 22

pSlice索引为2的值也会变成22,这时候两个slice的值如下:
pSlice
{0, 10, 22, 30, 40}
subSlice
{10, 22}

如果对subSlice做append操作呢?
要知道,subSlice的长度是2,容量是4,append操作也会反映到pSlice

//append操作会返回一个新切片,同样共享底层数组
subSlice = append(subSlice, 33) 

这时候两个slice的值如下:
pSlice
{0, 10, 22, 33, 40}
subSlice
{10, 22, 33}

你以为改的只是一个切片,其实,你改了人家全家啊!

第二个坑:for range遍历的是副本

遍历切片当然是用for range,简洁大方

slice := []string{"wo", "shi", "shui"}
for index, value := range slice {
  println(&value)
  println(&slice[index])
}

地址根本不一样啊!
在range中改值,你以为改变了他,其实他从来没变过,你只是改变了它

上一篇 下一篇

猜你喜欢

热点阅读