go切片的概念及用法
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章主要介绍"go切片的概念及用法",在日常操作中,相信很多人在go切片的概念及用法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"go切片的概念及用法"的疑惑有所帮
千家信息网最后更新 2025年12月02日go切片的概念及用法
这篇文章主要介绍"go切片的概念及用法",在日常操作中,相信很多人在go切片的概念及用法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"go切片的概念及用法"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
go切片原型
// runtime/slice.gotype slice struct { array unsafe.Pointer// 引用底层数组的指针 len int// 引用数组元素的长度,使用下标对元素进行访问的时候,下标不能超过len cap int // 引用数组的容量,cap>=len}定义一个名为baseSlice 的切片
baseSlice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}底层结构

定义一个新的切片slice1
slice1 := baseSlice[2:5] //[]int{2,3,4}底层结构
定义一个新的切片slice2
slice2 := slice1[4:7] //[]int{6,7,8}底层结构

源码
package mainimport ("fmt")func main() {baseSlice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}slice1 := baseSlice[2:5] //[]int{2,3,4} //这里slice1 cap是8,底层引用的数组为[]int{2, 3, 4, 5, 6, 7, 8, 9} //所以slice1 len=3, cap=8 //由于 slice1 cap=8 所以slice1[4:7]并不会发生数组越界 slice2 := slice1[4:7] //[]int{6,7,8} fmt.Printf("slice1:%v.len:%d.cap:%d\n", slice1, len(slice1), cap(slice1)) //slice1:[2 3 4].len:3.cap:8 fmt.Printf("slice2:%v.len:%d.cap:%d\n", slice2, len(slice2), cap(slice2)) //slice2:[6 7 8].len:3.cap:4}切片是值传递
package mainimport ("fmt")func main() {baseSlice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}slice1 := baseSlice[2:5] //[]int{2,3,4} appendSlice(slice1)fmt.Printf("slice1:%v\n", slice1) //slice1:[2 3 4] fmt.Printf("baseSlice:%v\n", baseSlice) //baseSlice:[0 1 2 3 4 10 6 7 8 9]}func appendSlice(s []int) { //值传递 s = append(s, 10) //这里会改变底层数组里的值,如果append的元素个数大于底层引用数组的容量,则会触发一次数组copy fmt.Printf("append slice1:%v\n", s) //append slice1:[2 3 4 10]}引用传递的假象
如果在调用的方法里,修改了传入切片len内的值,导致底层数组对应的值被修改,从调用方法外看,就像传入的切片值被修改了。
package mainimport ("fmt")func main() {baseSlice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}slice1 := baseSlice[2:5] //[]int{2,3,4} appendSlice(slice1)fmt.Printf("slice1:%v\n", slice1) //slice1:[123 3 4],看起来是slice1被修改了,其实是由于底层数组被修改的缘故 fmt.Printf("baseSlice:%v\n", baseSlice) //baseSlice:[0 1 123 3 4 5 6 7 8 9]}func appendSlice(s []int) { //值传递 // s = append(s, 10) s[0] = 123 //这里会改变底层数组里的值 fmt.Printf("append slice1:%v. len=%d. cap=%d\n", s, len(s), cap(s)) //append slice1:[123 3 4]. len=3. cap=8}深度copy
package mainimport ("fmt")func main() {baseSlice := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}slice1 := baseSlice[4:7] //[]int{6,7,8} fmt.Printf("slice1:%v\n", slice1) //slice1:[4 5 6] //slice 深copy slice2 := make([]int, 3, 3)copy(slice2, slice1)fmt.Printf("slice2:%v. len=%d. cap=%d\n", slice2, len(slice2), cap(slice2)) //slice2:[4 5 6]. len=3. cap=3 slice2[0] = 100fmt.Printf("slice2:%v\n", slice2) //slice2:[100 5 6] fmt.Printf("slice1:%v\n", slice1) //slice1:[4 5 6] fmt.Printf("baseSlice:%v\n", baseSlice) //baseSlice:[0 1 2 3 4 5 6 7 8 9]}扩容
// runtime/slice.go//cap 为满足存放数据的最小容量func growslice(et *_type, old slice, cap int) slice { ... if cap > doublecap { newcap = cap } else { if old.len < 1024 {//如果slice len<1024,扩容时容量增长2倍,也就是2个变4个 newcap = doublecap } else {//如果slice len>=1024,扩容时增加原来容量的四分之一 // Check 0 < newcap to detect overflow // and prevent an infinite loop. for 0 < newcap && newcap < cap {newcap += newcap / 4 } ... } }nil slice和empty slice
empty slice 底层数组指针指向实际存在的空数组的地址;
nil slice 底层数组指针指向的是nil;
package mainimport ( "fmt")func main() { var nilSlice []int emptySlice := make([]int, 0) if emptySlice == nil { fmt.Println("emptySlice is nil.") } if nilSlice == nil { fmt.Println("nilSlice is nil.") //输出 nilSlice is nil. }}tips:
Go 语言的函数参数传递,只有值传递。
到此,关于"go切片的概念及用法"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
数组
底层
容量
学习
元素
指针
方法
结构
下标
指向
更多
帮助
实用
最小
接下来
个数
假象
函数
原型
参数
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
2个g的数据库文件
香港有哪些软件开发商
jade没有办法读取数据库
怎么部署web服务器的
浙江现代软件开发品牌
网络安全信息会讲话
sql数据库做什么的
网络安全从我做起广播稿
服务器买回家要自己装系统吗
sql2008 数据库对比
开世览文数据库
z620安装苹果服务器
任务计划程序安全数据库在哪
服务器托管管理服务系统
服务器双机热备软件推荐
问道5周年服务器名称
软件开发岗工资
广西融安网络安全宣传
原生sql连接数据库
诗歌中的万方数据库
软件开发技术研究生工资
数据库直接导入数据安全吗
软件开发需要用到哪些技术
中国第一大互联网科技公司
武汉亘知网络技术有限公司
软件开发群体
在网络安全方面我们应该怎么做
sql数据库运维服务器
软件开发pl
网络安全与爱国主义