Go语言Slice的一道骚题

大家好我是一根甜苦瓜,今天我们来聊一道go语言中slice的面试题,加深一下对slice的理解

题目来自于雨痕大佬的《Go学习笔记》第四版,P43页

go 复制代码
func TestDemo(t *testing.T) {
	slice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	s1 := slice[2:5]     
	s2 := s1[2:6:7]      
	s2 = append(s2, 100)
	s2 = append(s2, 200)
	s1[2] = 20           
	t.Log(s1)            
	t.Log(s2)        
	t.Log(slice)
}

暂停5分钟,大家可以人脑编译一下,看看结果回事什么

时间到,公布答案

go 复制代码
=== RUN   TestDemo
    user_repo_test.go:21: [2 3 20]
    user_repo_test.go:22: [4 5 6 7 100 200]
    user_repo_test.go:23: [0 1 2 3 20 5 6 7 100 9]
--- PASS: TestDemo (0.00s)
PASS

是不是脑瓜子嗡嗡的呀?下面来图解这道题

先来看初始化 slices1s2 这三行代码:

● 第 22 行将 slice 初始化为一个数组,元素是 0-9 这没有什么好说的。

● 第 23 行,是在 slice 的基础上创建的 s1,选择下标范围 [2,5) 的元素来创建。左闭右开。容量为 3,cap 为 8

● 第 24 行,s2s1 的基础上创建,下标范围是 s1[2,6)cap 容量到了 7 号下标,容量为 4cap5

所以最终的三个对象的内存布局如下图:

接下来看代码s2 = append(s2, 100),由于 s2cap5,此时尚有一个空间可以插入,所以直接 append。但是由于共用了底层数组 s1slice,所以最终,他们三个变量都会被影响,最终结果如下:

接下来看代码s2 = append(s2, 200),此时 s2lencap 都为 5,那么在s2上继续添加元素显然不够用了,需要扩 容,扩容是新开辟了空间,将老数据复制过去,所以s2和老数组并无瓜葛了。这里是直接翻倍扩容(关于扩容大家可以去百度一下)。至此三个变量的内容如下。

最后再看这行代码 s1[2] = 20

这个就很简单了,此时 s1 还是和老数组有瓜葛的,所以一改全改但是不会影响到新开辟的 s2。最终三个数组/切片的情况就是下面这个图。

这里需要注意的是,由于打印 S1 的时候并不会把 len 以外的数据打印出来,所以最终输出结果是:

相关推荐
wuyk55517 分钟前
12.归并排序:分治思想的稳定排序算法
开发语言·数据结构·算法·排序算法
吴声子夜歌21 分钟前
ApacheCommons——commons-text(模板替换与文本算法)
java·开发语言·算法·apache
玉宇夕落1 小时前
背单词项目一:融会贯通:从零构建"单词大师"后台——Next.js + Supabase + Drizzle 全栈开发实战
后端
quantdash_cc1 小时前
量化数据源怎么选:稳定性、实时性和数据完整性到底该如何权衡?
开发语言·python·数据分析·量化交易·股票数据·quantdash
橙序员小站1 小时前
从 Demo 到生产:Agent Harness 如何把 AI 真正“接”进项目
后端·aigc·ai编程
萧瑟余晖1 小时前
Java深入解析篇五十四之对象模型详解
java·开发语言
她的男孩1 小时前
一个开源低代码框架的协作 SPI 是怎么设计的 ForgeAdmin 拆解 + 实战接入新平台
后端·算法·架构
蓝山6161 小时前
Python 字典(Dictionary)完全指南:从入门到实战
后端
foggyprojects2 小时前
在 DeepSeek Harness 里跑通 Foggy:从安装插件到第一次问数
后端
张文是假的啊2 小时前
Java | record | Controller逻辑
java·开发语言