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) }总结
完美的三篇文章!应对实际开发中绝大部分场景。
红色印记团一大纪念馆团一大纪念馆正门。1922年5月5日至10日,中国社会主义青年团第一次全国代表大会在广州东园召开。到会代表25人,代表全国15个地区团组织的5000多名团员。大会通过了中国社会主义
建教育基地续红色血脉湖南省税务局党建工作处深入平江县李六如故居调研红网时刻岳阳12月5日讯(通讯员方平红朱道远)为发挥好平江县红色旅游资源,加快推进李六如故居税收红色教育基地建设。12月3日,国家税务总局湖南省税务局党建工作处处长罗少宇等一行深入
游戏王怪兽卡昆虫族(8)住在冰结界的魔醉虫氷結界住魔酔蟲住在冰结界的魔醉虫氷結界住魔酔蟲自然甲虫自然甲虫沙漠守护者砂漠守護者沙漠守护者砂漠守護者十字剑猎手十字剑猎手自然蜘蛛牙自然蜘蛛牙自然蜻蜓
40岁凯特王妃一身红色礼服艳压全场,无视哈里梅根不断挑衅昨晚,威尔士王妃与威尔士亲王一起走出白金汉宫,参加一年一度的外交使团招待会,她穿着一件猩红色的珍妮帕克汉姆礼服艳惊四座。40岁的凯特王妃(Kate)身着备受青睐的英国时装设计师设计
宝宝便便颜色异常,身体是否健康?从性状到颜色教你识便宝宝的便便是张晴雨表,一定程度上能反映宝宝的健康状况。刚出生宝宝的胎便喝母乳宝宝的便便喝配方奶粉宝宝的便便添加辅食宝宝的便便不同的喂养方式,导致便便的颜色和性状大不相同。今天这篇有
节日季将至,会穿红色和会送礼一样重要年末将至,大街上已满是节日气息。圣诞元旦新年,最近的生活就是在等这些节日的到来,以及迫不及待要享受和朋友家人小聚的时光了。热闹的节日氛围里,到底还是红色招人稀罕。本身亚洲人的黄肤色
什么是红色金子?希腊西红花茶来自地中海的天然茶饮欧洲人都称之为红色金子在古代都是王宫贵族所享用亚历山大大帝常用它来泡茶饮用并且靠它来强健身体,提高免疫力埃及艳后,也钟爱着红色金子她不但饮用,还用来
西兰花炒前加一步,菜品油亮,颜色鲜亮,清脆爽口,下酒佐餐均可大家好,我是舒晨,每天在这里分享各种家常美食,今天给大家分享简单小炒清炒西兰花。西兰花是十字花科芸薹属植物,主根基部粗大,根系发达。西兰花主要食用部分是脆嫩的花茎和短缩肥嫩的花薹及
外媒报道中国电动汽车获欧洲五星安全评价据西班牙公众日报网站11月27日报道,中国电动汽车强势出击,获得EuroNCAP安全五星评价。报道称,关于中国汽车的疑虑已经所剩无几。在短短几年内,随着中国汽车在欧洲大陆的销量持续
事实证明,赵丽颖,已经活成了一个符号文阅栀编辑阅栀赵丽颖,一个标签是土气和尴尬的演员。何幸福谢幕不久,胖子半夏带着她的嚣张与土气再次回来,网友忍不住发问这个笑起来有褶子且油腻的女演员,还是古偶剧中的小白花吗?早就不是
李少莉为何要精致打扮?听一下她自己是怎么评价自己的李少莉,因为念稿和耳环丝巾一下子被推上了风口浪尖,关于这位女人的故事,如今还在持续着。对于李少莉精致打扮自己的行为,很多人也是议论纷纷,就连她所在地方的相关人员也说已经介入调查。对