在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
slice 三个属性golang 的slice是一个指向底层的数组的指针结构体。 这个结构体有三个属性,1.指向数组指针,2.len: slice中元素的数量 3.cap:slice占用内存数量。 只有深刻理解这三个属性才能在使用slice中不至于犯错。 切片的一个必须知道的 当切片长度超过容量时,底层数组会重新分配内存空间(扩容) ,那么append会指向新切片没扩容的切片 slice1 := make([]int ,4,10) //这里指定了容量 for i:=1; i<5; i++{ slice1[i-1] = i } slice2 := slice1 slice2 = append(slice2,2) slice1[2] =999 fmt.Printf("slice1:%v slice2:%v",slice1,slice2) 运行结果是: slice1:[1 2 999 4] slice2:[1 2 999 4 2] slice1 := make([]int ,4) //这里没指定容量 for i:=1; i<5; i++{ slice1[i-1] = i } slice2 := slice1 slice2 = append(slice2,2) slice1[2] =999 fmt.Printf("slice1:%v slice2:%v",slice1,slice2) 运行结果是:slice1:[1 2 999 4] slice2:[1 2 3 4 2] slice被扩容了因此底层数组内存地址被重新分配了 正确理解变量和共享
以上是golang 圣经中的一句话。深刻理解这句话对于日程编程非常有意义。 1.什么时候共享数据会被其他变量修改
运行结果
我们清楚的看到了数据共享,此时修改了a1 ,两位两个变量都被修改 什么时候不会修改
运行结果
可以虽然a1被修改,a2并没有修改。我们知道append函数会面临内存的重新分配。所以等a2进行append的时候,会重新申请内存空间,将原有数组拷贝然后增加如新值。也就是当append操作的时候,此时a2 不在和a1 共享内存了。所以后续对a1的操作是不会影响到a2. 3.所有的append操作都会隔断内存共享?
运行结果
这次a3 是对a1进行切片操作赋值的新变量。此时对a3进行append操作,我们发现a1的值同步被修改了。所以此时a3 和a1 仍然是共享内存,append并没有申请新的内存空间而是继续在a3的数据末尾写入,这样对于a1 是覆盖了原有值。 问题本质是
重新运行后将三个变量cap值打印为以上输出。 总结在对slice 复制的时候,如果面临多个变量同时指向一个数组的时候,一定要考虑到数据的共享和内存的重新分配。
作者:橙知 |
请发表评论