6.3 Go 切片技巧学习笔记
6.3 Go 切片技巧学习笔记1. 删除指定索引的元素 — append 切片拼接Go 没有内置的删除元素操作用append把前半段和后半段拼接起来packagemainimportfmtfuncmain(){data:[]int{1,2,3,4,5,6,7,8,9,10}// 删除索引3的元素值4// append(data[:3], data[4:]...) → [1,2,3] [5,6,7,8,9,10]index:3dataappend(data[:index],data[index1:]...)fmt.Println(After removing index 3:,data)}执行结果After removing index 3: [1 2 3 5 6 7 8 9 10]要点data[:index]— 索引之前的元素[1, 2, 3]data[index1:]— 索引之后的元素[5, 6, 7, 8, 9, 10]append(data[:index], data[index1:]...)— 把两段拼接中间的元素 4 被删除这是 Go 删除切片元素的标准模式append 前半段 后半段注意这个操作修改了底层数组删除后 data 的长度变短但底层数组末尾仍有一个残留元素原 data[9]10 被复制到新位置旧位置仍有值只是不可访问如果元素是指针类型或包含指针需先置 nil 防止内存泄漏data[index]nil// 先置空再 appenddataappend(data[:index],data[index1:]...)2. 在指定索引插入元素 — 双层 append插入元素也用 append分三步取前半段 → append 新值 → append 后半段packagemainimportfmtfuncmain(){data:[]int{1,2,3,5,6,7,8,9,10}// 删除4之后的切片// 在索引2处插入值99insertIndex:2insertValue:99// 步骤拆解// 1. append(data[:2], 99) → [1, 2, 99]// 2. append([1, 2, 99], data[2:]...) → [1, 2, 99, 3, 5, 6, 7, 8, 9, 10]dataappend(append(data[:insertIndex],insertValue),data[insertIndex:]...)fmt.Println(After inserting 99 at index 2:,data)}执行结果After inserting 99 at index 2: [1 2 99 99 5 6 7 8 9 10]要点append(data[:insertIndex], insertValue)— 在前半段末尾追加新值得到 [1, 2, 99]append([1,2,99], data[insertIndex:]...)— 拼接后半段得到 [1, 2, 99, 3, 5, …]双层 append 嵌套内层 append 返回的切片作为外层 append 的第一个参数注意输出中有两个 99这是因为内层append(data[:2], 99)在原底层数组上操作data[:2] [1, 2]append 99 后底层位置 data[2] 被写为 99外层append([1,2,99], data[2:]...)中data[2:]从原底层数组读取data[2] 已经是 99所以出现了两个 99 — 这是 append 在共享底层数组上操作的副作用更安全的做法先复制前半段到新切片避免修改原底层数组// 安全版本使用临时切片temp:make([]int,insertIndex)copy(temp,data[:insertIndex])tempappend(temp,insertValue)dataappend(temp,data[insertIndex:]...)3. 原地反转切片 — 双指针交换用两个指针从两端向中间交换元素时间复杂度 O(n)空间复杂度 O(1)packagemainimportfmtfuncmain(){numbers:[]int{1,2,3,4,5}// 双指针i 从头开始j 从尾开始交换后 i j--fori,j:0,len(numbers)-1;ij;i,ji1,j-1{numbers[i],numbers[j]numbers[j],numbers[i]}fmt.Println(Reversed numbers:,numbers)}执行结果Reversed numbers: [5 4 3 2 1]要点for i, j : 0, len(numbers)-1; i j; i, j i1, j-1— 初始化两个指针i j-- 同时更新numbers[i], numbers[j] numbers[j], numbers[i]— Go 的多重赋值同时交换两个元素i j— 当 i 和 j 相遇或越过时停止奇数长度时中间元素不交换原地操作不需要额外空间直接在原切片上交换交换过程1↔5 → 2↔4 → 3不动中间→ 结果 [5, 4, 3, 2, 1]Go 没有内置的反转函数这是反转切片的标准写法Go 官方 Wiki 推荐4. 过滤删除所有指定值 — append 收集保留值遍历切片把不等于目标值的元素收集到新切片packagemainimportfmtfuncmain(){values:[]int{1,2,3,2,4,2,5}target:2// 创建新切片收集非目标值varfiltered[]intfor_,v:rangevalues{ifv!target{filteredappend(filtered,v)}}fmt.Printf(After removing all %d: %v\n,target,filtered)}执行结果After removing all 2: [1 3 4 5]要点var filtered []int— nil 切片append 自动分配底层数组遍历原切片v ! target时 append 到新切片结果[1, 3, 4, 5]— 所有 2 被移除这是过滤模式遍历 条件判断 appendGo 中极常用更高效的就地版本不分配新底层数组n:0for_,v:rangevalues{ifv!target{values[n]v n}}valuesvalues[:n]// 截断到新长度5. 检查切片是否包含某值 — 手动遍历Go 1.18 之前没有内置的contains函数需要手动遍历Go 1.21 有slices.Containspackagemainimportfmtfuncmain(){haystack:[]string{apple,banana,cherry,date}needle:cherryvarfoundboolfor_,item:rangehaystack{ifitemneedle{foundtruebreak// 找到后立即退出}}iffound{fmt.Printf(Found %s in slice\n,needle)}else{fmt.Printf(%s not found in slice\n,needle)}}执行结果Found cherry in slice要点遍历切片逐个比较break找到后立即退出var found bool— 默认值 false找到后设为 trueGo 1.21 可以用slices.Contains(haystack, needle)更简洁importgolang.org/x/exp/slices// 或 Go 1.21: slicesfound:slices.Contains(haystack,needle)对于排序切片可以用二分搜索提高效率sort.SearchStrings(slice, target)6. 去重 — map 记录已见元素用 map 的键来跟踪哪些元素已经出现过实现去重packagemainimportfmtfuncmain(){duplicates:[]int{1,2,2,3,1,4,3,5}// map 记录已见元素只保留首次出现的seen:make(map[int]bool)varunique[]intfor_,v:rangeduplicates{if!seen[v]{// v 还没出现过seen[v]true// 标记为已见uniqueappend(unique,v)// 加入结果}}fmt.Println(Unique elements:,unique)}执行结果Unique elements: [1 2 3 4 5]要点seen : make(map[int]bool)— map 的键是元素值bool 标记是否已见!seen[v]— v 不在 map 中 首次出现加入结果并标记seen[v] true— 标记已见下次遇到相同值时跳过结果[1, 2, 3, 4, 5]— 保持了首次出现的顺序去重效率O(n) 时间map 查找是 O(1)O(n) 空间map 和结果切片如果不关心顺序直接用 map 的键即可seen:make(map[int]struct{})// struct{} 不占内存for_,v:rangeduplicates{seen[v]struct{}{}}unique:make([]int,0,len(seen))fork:rangeseen{uniqueappend(unique,k)}// 注意map 遍历顺序不确定知识点总结知识点关键概念删除元素append(data[:i], data[i1:]...)— 前半段 后半段拼接插入元素append(append(data[:i], val), data[i:]...)— 双层 append注意底层数组副作用反转切片双指针交换for i,j : 0,len-1; ijGo 官方推荐写法过滤删除遍历 条件判断 append 收集保留值包含检查手动遍历 breakGo 1.21 用slices.Contains去重map[元素]bool记录已见保持首次出现顺序

相关新闻

Springboot应用开发工具类整理

Springboot应用开发工具类整理

目录一、编写目的二、映射工具类2.1 依赖2.2 代码三、日期格式3.1 依赖3.2 代码四、加密4.1 代码五、Http请求5.1 依赖5.2 代码六、金额6.1?代码七、二维码7.1 依赖7.2 代码八、坐标转换8.1 代码九、树结构9.1?代码9.1.1 节点?9.1.2 工具类十、结语* * > Welcome to Code…

2026/10/21 23:21:41 阅读更多 →
自动驾驶中间件设计:从车辆到机器人的跨平台技术栈迁移

自动驾驶中间件设计:从车辆到机器人的跨平台技术栈迁移

智驾公司的终局不是汽车,而是把自动驾驶研发过程中沉淀下来的传感器融合、定位建图、决策规划、仿真评测和数据闭环能力,复制到更多移动平台上。判断一家智驾公司是否具备长期价值,不能只看它做出了多少款量产车型,更要看它的技术…

2026/10/24 7:30:22 阅读更多 →
从磁阻来推αβ轴磁链和电感

从磁阻来推αβ轴磁链和电感

IPMSM内置式电机,因为转子d轴上内置了永磁体,所以导致定子线圈产生的磁场,通过d轴时的磁路的总磁阻Rd > 通过q轴时的磁路的总磁阻Rq,所以磁通量会大部分在q轴,少部分在d轴,α轴(β轴)线圈的磁场&#xf…

2026/10/25 12:03:41 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/26 12:00:21 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/25 22:36:10 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/26 4:52:12 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/26 12:00:21 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/26 5:00:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/26 3:16:46 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 12:00:19 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 13:21:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/26 8:34:37 阅读更多 →