对切片删除操作的一些疑问?

对切片删除操作的一些疑问?

问题描述:

切片的底层是一个数组指针对象,根据官网博客 Go Slices: usage and internals - The Go Blog (golang.org) 的介绍,没整明白下方代码(如截图)


我的疑问:

1、为什么删除头部元素的时候其容量会发生改变呢?

2、切片的底层也会一个数组,那么其内存地址也应该是连续的才对,我删除中间的元素此时的内存地址不应该是断裂了会开辟一个新的连续内存空间来存放吗(就跟切片扩容一样),但实际这里我验证后,我的理解是错误的。


http://img1.sycdn.imooc.com//climg/60df429c090f57ec11170707.jpg

相关代码:

package main

import "fmt"

func main() {
fmt.Println("======切片删除测试:slice[i:x]========")
slice := []int{-5,-4,-3,-2,-1,0, 1, 2, 3, 4}
fmt.Printf("源切片:%v len:%d cap:%d ptr:%p slice[1]:%p\n", slice, len(slice), cap(slice), slice, &slice[1])

fmt.Println("==========删除尾部元素================")
slice = slice[:len(slice)-1]
fmt.Printf("删除尾部:%v len:%d cap:%d ptr:%p slice[1]:%p\n", slice, len(slice), cap(slice), slice, &slice[1])

fmt.Println("==========删除头部元素================")
slice = slice[1:]
fmt.Printf("删除头部:%v len:%d cap:%d ptr:%p\n", slice, len(slice), cap(slice), slice)

fmt.Println("==========删除中间元素================")
center := int(len(slice)/2)
slice = append(slice[:center], slice[center+1:]...)
fmt.Printf("删除中间:%v len:%d cap:%d ptr:%p\n", slice, len(slice), cap(slice), slice)
}


尝试过的解决方式:

1、我看了 runtime/slice.go 中的源码,貌似没有找到关于删除操作对应的代码(感觉我应该是找错了)

2、使用了 dlv 来 debug,还不是很熟练也没 debug 出什么东西

3、通过 google 查了 `golang slice delete first element cap changed` 翻了几篇文章,没有找到对应的答案

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
Xargin 2021-07-03 19:22:31
slice = slice[1:]

你这是相当于生成了一个新的 slice,并且把原来的覆盖掉了


你试试 slice2 = slice[1:],再看看 cap(slice2) 和 cap(slice)

  • 提问者 L_M_S #1

    谢谢曹大,我今天在  A Tour of Go (golang.org) 里应该找到答案,忘记关这个提问了。

    我理解如下:

    slice = slice[:len(slice)-1]

    这个也是一个新切片并覆盖了原来的。在 Tour fof Go中看到这么一句:

    The capacity of a slice is the number of elements in the underlying array, counting from the first element in the slice.


    应该是新切片对应的头指针(the first element in the slice)发生了改变,所以计算容量的时候会变动。而 slice = slice[:len(slice)-1] 这个新切片的头指针是没有改变的。

    2021-07-03 21:39:18
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师