Go开发03切片彻底研究(三)
这篇根据底层分析切片
切片实际对应的是一个结构type Slice struct{ array unsafe.Pointer len int cap int }
三个成员依次是数据指针 ,长度 和容量 。现在我们主要来看函数调用func test_slice(b []int) { b = append(b, 100) fmt.Println(b) } func main() { //创建切片a,长度为0,容量为10 var a = make([]int, 0, 10) //追加5个元素之后,长度为5,容量为10 a = append(a, 1, 2, 3, 4, 5) //调用函数 test_slice(a) fmt.Println(a) }
代码比较简明,我们重点看实参 和形参 。
如前文所述,切片对应的是一个结构,那么可以认为把实参a传过去,相当于将a的结构体 传过去,这一步理解至关重要。
接着,形参实参一结合,b就得到一份a的结构副本 。由于当前a容量还有5个元素,因此追加100之后,没有扩容。所谓的扩容主要就是指结构成员的array指针发生变化 。
因此b和a依然共享同一段切片内存。打印结果b=[]int{1,2,3,4,5,100},但是打印a却等于a=[]int{1,2,3,4,5},没有发生变化,这是为什么呢?
原因就在于,切片b追加之后,它的长度len也跟着变化。但是原来a的结构体内部的len并没有变化¹ ,因此为了能看到a确实共享同一个切片,需要将a的切片长度进行修正 。
¹ 补充:如果学过C语言,我们想像有一个结构类型 struct Slice{ int a; int b; int c; };
当将结构传值传过去时,成员a,b,c就复制一个副本,因此,如果副本发生变化和原结构一点都没关系。类比切片的结构,len是一个int,也是一样只是传个副本... test_slice(a); a=a[:6] //修正a的长度 fmt.Println(a)
再次打印可以看到1,2,3,4,5,100。扩容导致指针变化
现在我们看一下扩容的例子func test_slice(b []int) { //追加三个元素,导致切片扩容 b = append(b, 20,21,22) fmt.Println(b) } func main() { //创建切片a,长度为0,容量为10 var a = make([]int, 0, 10) //追加8个元素之后,长度为8,容量为10 a = append(a, 1, 2, 3, 4, 5, 6, 7, 8) //调用函数 test_slice(a) fmt.Println(a) }
分析:
调用函数后,由于追加3个元素,而原切片只剩2个元素,因此需要切片扩容。所谓切片扩容用一个词来形容就是"另起炉灶 ",和原切片完全脱离关系,因为是在新内存中创建的。
那么b结构体中的array指针发生变化,指向新地址值。而原切片由于脱离关系不受干扰,还是原样。
结果:
b=[]int{1,2,3,4,5,6,7,8,20,21,22}
a=[]int{1,2,3,4,5,6,7,8}
想通过函数改变原切片
如果就想通过函数改变原切片怎么办呢?上面的例子我们可以看出,实际是一个值传递的问题,我们能不能牢牢的控制结构内部的指针还属于a呢?自然就想到将切片的指针传过去,相当于C语言中将结构体的地址传过去 。//形参传为切片的地址 func test_slice(b *[]int) { //追加三个元素,导致切片扩容 *b = append(*b, 20,21,22) fmt.Println(*b) } func main() { //创建切片a,长度为0,容量为10 var a = make([]int, 0, 10) //追加8个元素之后,长度为8,容量为10 a = append(a, 1, 2, 3, 4, 5, 6, 7, 8) //调用函数,传切片地址 test_slice(&a) fmt.Println(a) }总结
完美的三篇文章!应对实际开发中绝大部分场景。
夏季家电新品上架,新风空调受追捧,康佳新品开启预约虽然最近的天气有些变化无常,但毫无疑问的是夏天不会迟到,连续的高温天气即将来袭,风扇空调这类夏季家电产品提前进入了热销阶段,而各家家电厂商也已经抓住初夏阶段,推出各自的风扇或空调夏
有人顺流而下,有人逆流而上在你自己的时区里,一切都准时文舒平最近,豆瓣上一个分享个人成长经历的逆社会时钟小组引起了大家的热议。所谓社会时钟,是用来描述个体生命中主要里程碑的心理时钟,也就是我们常说的什么年龄做什么事,而在那些逆社会时钟
中国人民银行货币政策司原司长孙国峰被查据中央纪委国家监委驻中国人民银行纪检监察组天津市监察委员会5月18日消息中国人民银行货币政策司原司长孙国峰涉嫌严重违纪违法,目前正接受纪律审查和监察调查。(资料图)公开履历显示,孙
茶叶和大蒜混合在一起,解决了很多朋友的困扰,知道的人不多大蒜可以说是厨房中必备的调味品,常吃大蒜对身体有很多好处。茶叶是很多人都会喝的,而且也送礼佳品,这两样东西看起来不搭边,但是把大蒜和茶叶这两种毫不相干的东西放在一起却能起大作用,能
文案520朋友圈签名背景图520文案想认真谈场恋爱从你开始没有结束每天早上醒来,看见你和阳光都在那就是我想要的未来把所有的温柔和可爱都设置成了仅你可见我要陪你从新鲜感走到归属感和安全感喜欢是藏不住的所以还是
凌晨3点!资深媒体人曝出争议猛料中国足球遭重创,球迷吐槽声一片北京时间5月19日凌晨3点,中国足球传来最新消息,日前,针对中超各球队的情况,国内资深媒体人李璇曝出争议猛料,她表示其实联赛里像重庆队一样欠薪的还挺多的,只是没有暴雷,而这样的爆料
这道题,古今中外无人能解爱的N次方,答案知多少?520是5月留给我们最大的惊喜最暖的浪漫天地之恩亲友之情伴侣之恋万物之美一声爱可抵百语千言那爱叠加累积成爱的N次方又能包容多少美好情感?今年520让我们再会桥头集聚焦2022中国肥
我们这十年车过觉巴山为宣传展示党的十八大以来文化旅游业改革创新亮点和辉煌发展成就,生动呈现文化旅游发展带给百姓游客实实在在的幸福感和获得感,为迎接党的二十大胜利召开营造良好的舆论氛围,人民日报社民生周
2022年新春自驾游之一冬季走青藏线进藏真不容易从北京出发,自驾车进藏旅游,我经历过许多次。但2022年2月的这一回,与以往不同。首先,它是我首次冬季进藏其次,它是我首次从青藏线进藏。两个首次叠加在一起,所产生的最大感受,就仨字
山系生活迎来新热潮,崂山值得奔赴!什么是山系生活?2022年十大生活趋势,里面是这么说的憋了太久要去户外走走,城市青年爱上山系生活,玩在户外,山系是周末新选择,穿上户外,山系是穿搭新风格。露营登山越野跑不仅仅局限于
旅游纪念品如何告别直白设计和千篇一律全球新冠肺炎疫情已进入第三年,旅游业受到严重打击,旅游纪念品本就在旅游商品中占比甚微,伴随着旅游人数的大幅下降,多数旅游纪念品生产企业更是难以为继。为了生存,这些企业也要进行供给侧