记录一下遇到的切片append删除元素的问题

本文探讨了Go语言中切片在删除元素后的行为,揭示了切片如何覆盖底层数组的值。通过实例解析了切片的容量、引用特性和删除操作的影响,强调了切片在内存管理中的独特性质。对于想要深入了解Go语言切片特性的读者,本文提供了关键的洞察。
摘要由CSDN通过智能技术生成

一开始,我以为切片在删除元素后底层数组的元素也会相应的删除,最后结果会是[0 1 3 0 4],但最后结果是[0 1 3 0 4 2 2 2]。

然后开始各种找切片本质原因,最后知道了,删除元素之后的切片会覆盖掉底层数组位置的元素。

 在这里可以看到,第一次循环后结果是[0 1 2 3 0 4 2],此时底层数组原本是[0 1 2 2 3 0 4 2],原本0,1,2,2,3,0,4的位置就被[0 1 2 3 0 4 2]覆盖了,变成了[0 1 2 3 0 4 2 2],第二次循环结果是[0 1 3 0 4 2],一样的,此时底层数组是[0 1 2 3 0 4 2 2],0,1,2,3,0,4的位置被[0 1 3 0 4 2]替换覆盖了,最终打印出来的切片就变成了[0 1 3 0 4 2 2 2]。

 最后疑惑解除,在此列举一些切片特性。

1、切片的容量是底层数组的元素个数。

2、切片的切片指向的还是同一个底层数组。

3、切片的属于引用,底层是一个数组。切片相当于一个框,框住你引用的范围。

4、切片追加元素如果容量不够,会新开辟一个底层数组。

5、切片传参使用时,是值拷贝,但是是切片地址的值。

6、最后就是这个问题,切片删除元素操作,会覆盖底层数组的值。

希望能给以后有这个疑惑的老板看到解决心中的疑惑。

### 回答1: Go 语言中的 append 函数用于将一个或多个元素附加到切片的末尾。append 切片分配新的内存空间,并复制旧切片的数据,将新元素添加到新的内存空间中。而 append 元素则只是将元素添加到切片的原有内存空间中。 ### 回答2: 在Go语言中,使用`append`函数来添加元素到一个切片中。无论是向一个切片中`append`元素,还是向一个切片追加另一个切片,它们在内存分配上有些许区别。 当向切片中`append`一个元素时,如果切片的容量足够容纳新的元素,那么直接将元素添加在切片的末尾。这意味着元素是直接被追加到原切片的内存区域上的,不重新分配内存。如果切片的容量不足以容纳新元素,那么Go语言切片分配一块新的内存区域,并将原切片中的元素和新的元素都复制到这块新内存区域上,并返回一个指向新内存区域的切片。 当向切片中`append`另一个切片时,Go语言首先比较目标切片的容量和要追加切片的长度。如果目标切片的容量足够容纳要追加切片的元素,那么直接将要追加切片的元素复制到目标切片的内存区域上,并返回一个指向目标切片切片。这种情况下,不进行内存的重新分配和复制。如果目标切片的容量不足以容纳要追加切片的元素,那么Go语言为目标切片和要追加切片分配一块新的内存区域,并将两个切片的元素都复制到这块新内存区域上,并返回一个指向新内存区域的切片。 总结起来,当向切片`append`元素或另一个切片时,如果切片的容量足够,不重新分配内存;如果容量不足,将重新分配内存并复制元素。 ### 回答3: 在Go语言中,使用`append`函数可以向切片中追加元素。在进行`append`操作时,涉及到内存分配的问题。 首先,切片和数组的区别在于切片是一个引用类型,它的底层指向一个数组。切片本身并不存储元素,而是存储了一个指向底层数组的指针、切片的长度和容量。当切片的容量不足以容纳新的元素时,就需要进行内存扩容操作。 对于切片的`append`操作,当切片的容量不足时,创建一个新的底层数组,并将原来的元素复制到新的底层数组中。新的底层数组的容量通常是原来的两倍,并且根据实际情况进行调整。然后,将新的元素追加到新的底层数组中,并更新切片的指针、长度和容量。 值得注意的是,由于切片本身是一个指向底层数组的指针,并不需要像数组那样重新赋值给一个新的变量。因此,对切片进行`append`操作并赋值给切片本身,在原有的切片上进行操作,而不是创建一个新的切片。 一般情况下,`append`操作的时间复杂度为O(1),但是当底层数组发生扩容时,时间复杂度升至O(n)。此外,由于底层数组的复制操作涉及到内存分配和数据拷贝,`append`操作也产生额外的内存开销。考虑到性能方面的原因,如果预先知道切片的容量大小,可以使用`make`函数初始化切片并指定容量,以减少切片的扩容次数,从而提高性能。 综上所述,golang的`append`切片和元素的内存分配区别在于:`append`切片根据实际情况进行底层数组的内存扩容,并重新分配内存,同时对切片本身的指针、长度和容量进行更新;而`append`元素只需要将新的元素追加到底层数组的末尾,并不涉及内存扩容操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值