GO语言基础-04-数据类型-04-切片[slice](声明切片、初始化切片、切片赋值、切片长度、切片容量、空切片、append、copy)
数组和切片的区别
数组是需要指定个数的,而切片则不需要。
1. 声明切片
定义一个切片,且切片成员为字符串类型
2. 初始化切片
声明切片的同时,为切片分配一个内存地址。
2.1 切片长度
2.1.1 初始化指定长度的切片
说明:len表示数组长度,即切片的初始长度
| var slice1 = make([]type, len) |
在函数内,可简写做:
| slice1 := make([]type, len) |
| var names = make([]string,3) |
函数内可以写做:
| names := make([]string,3) |
当然你也可以先声明,然后在初始化
| var names []string |
| names = make([]string,3) |
2.1.2 查看切片长度 len()
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := make([]string,10) |
| fmt.Printf("切片:%+v\n长度为:%d",names,len(names)) |
| } |
结果打印
问:明明打印的切片没有成员,为什么长度为10?
答:可以看见我们打印出的结果是[ ]
而不是[]
。这里边有9个空格,即是10个成员间的9个分隔符(空格)。我们看不到成员,是因为这10个成员的值默认都是空(字串不赋值默认为空)。如果我们定义切片成员类型是int
我们将看到打印出10个0
(int类型不赋值,默认为0)
| package main |
| |
| import "fmt" |
| |
| func main() { |
| slice1 := make([]int,10) |
| fmt.Printf("切片:%+v\n长度为:%d",slice1,len(slice1)) |
| } |
结果:
| 切片:[0 0 0 0 0 0 0 0 0 0] |
| 长度为:10 |
2.2 切片容量
2.2.1 初始化指定容量的切片
说明:
每增加 一个成员,len 值加1,成员数达到cap值后,cap值翻倍。
| slice1 := make([]type, len, cap) |
| names := make([]string,3,5) |
2.2.2 查看切片长度 len()
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := make([]string,3,5) |
| fmt.Printf("切片长度为:%d,容量为:%d",len(names),cap(names)) |
| } |
结果打印
3 切片赋值
3.1 直接赋值
在函数内我们用:
在赋值的同时也声明了切片(只用=
仅赋值但不能声明切片)
| names :=[]string{"刘备","关羽","张飞" } |
| package main |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names)) |
| } |
结果显示
| 打印切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
3.2 引用数组给切片赋值
| package main |
| |
| import "fmt" |
| |
| func main() { |
| namesArray := [3]string{"刘备","关羽","张飞"} |
| names := namesArray[:] |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names)) |
| } |
执行结果为:
| 打印切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
3.3 引用数组某区间给切片赋值
前提:设N
为起始位置,到第M
个成员。
3.3.1 从数组位置N个取到第M个元素,赋值给切片
- 语法
- 示例
- 需求:从元素的位置1(刘备是位置0,关羽是位置1),取到第3个成员(第一个成员是刘备,第二个是关羽,第三个是张飞)
- 预计:切片将取到 关羽、张飞两个成员。
| package main |
| |
| import "fmt" |
| |
| func main() { |
| namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} |
| names := namesArray[1:3] |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names)) |
| } |
长度是2,因为我们取到了两个成员:关羽、张飞
容量是4,这是从起始位置1(关羽)起,计算到数组结尾(诸葛亮),一共四个位置。
虽然没有取到赵云和诸葛亮,但是容量已经加进来了
3.3.2 从数组位置N取到结尾,赋值给切片
- 语法
- 示例
| package main |
| |
| import "fmt" |
| |
| func main() { |
| namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} |
| names := namesArray[1:] |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names)) |
| } |
| 打印切片:[关羽 张飞 赵云 诸葛亮] |
| 长度为:4 |
| 容量为:4 |
- 说明
长度是4,因为我们取到了4个成员:关羽、张飞、赵云、诸葛亮
容量是4,这是从起始位置1(关羽)起,计算到数组结尾(诸葛亮),一共四个位置。
3.3.3 从开头取到第M个元素,赋值给切片
- 语法
- 示例
| package main |
| |
| import "fmt" |
| |
| func main() { |
| namesArray := [5]string{"刘备","关羽","张飞","赵云","诸葛亮"} |
| names := namesArray[:3] |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d",names,len(names),cap(names)) |
| } |
结果打印
| 打印切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:5 |
- 说明
长度是3,因为我们取到了3个成员:刘备、关羽、张飞
容量是5,这是从起始位置0(刘备)起,计算到数组结尾(诸葛亮),一共四个位置。
3.4 通过切片赋值给切片
说明:通过切片s初始化切片s1
方法同数组赋值给切片
4. 空切片
4.1 仅声明的切片为空
| package main |
| |
| import "fmt" |
| |
| func main() { |
| var names []string |
| |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| if names == nil { |
| fmt.Printf("切片是空的") |
| }else { |
| fmt.Println("切片不为空") |
| } |
| } |
4.2 初始容量为0的切片不为空
| package main |
| |
| import "fmt" |
| |
| func main() { |
| var names = make([]string,0,0) |
| fmt.Printf("打印切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| if names == nil { |
| fmt.Println("切片是空的") |
| }else { |
| fmt.Println("切片不为空") |
| } |
| } |
结果打印
5. append()
- 语法
| func append(slice []Type, elems ...Type) []Type |
| names = append(names,"赵云") |
- 示例1(添加一个成员)
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| names = append(names,"赵云") |
| fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| } |
| 原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
| ================== |
| 添加成员后:[刘备 关羽 张飞 赵云] |
| 长度为:4 |
| 容量为:6 |
结果可见,当成员达到容量上限后,再添加成员,长度增加一,但是容量会翻倍。
- 示例2(添加多个成员)
我们再继续添加成员,也想验证一下长度和容量的变化。
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| names = append(names,"赵云") |
| fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| |
| names = append(names,"马超","黄忠","魏延") |
| fmt.Printf("==================\n添加成员后:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| } |
| 原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
| ================== |
| 添加成员后:[刘备 关羽 张飞 赵云] |
| 长度为:4 |
| 容量为:6 |
| ================== |
| 添加成员后:[刘备 关羽 张飞 赵云 马超 黄忠 魏延] |
| 长度为:7 |
| 容量为:12 |
可以看到,成员再次超过容量时,容量在当前容量的基础上翻倍。
- 示例3(添加成员赋值给新切片)
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| names2 := append(names,"赵云") |
| fmt.Printf("==================\n新切片:%+v\n长度为:%d\n容量为:%d\n",names2,len(names2),cap(names2)) |
| fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| } |
| 原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
| ================== |
| 新切片:[刘备 关羽 张飞 赵云] |
| 长度为:4 |
| 容量为:6 |
| ================== |
| 再次打印原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
结果可见,append对于原切片并不会造成影响。
6. copy() 函数
- 语法
| func copy(dst []Type, src []Type) int |
返回成功拷贝了多少个元素
- 示例1(新切片长度 >= 原切片长度)
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| names2 := make([]string,4,4) |
| num := copy(names2,names) |
| fmt.Printf("==================\n新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2)) |
| fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| } |
| 原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
| ================== |
| 新切片:[刘备 关羽 张飞 ] |
| 拷贝了3个元素 |
| 长度为:4 |
| 容量为:4 |
| ================== |
| 再次打印原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
如上可见,初始化长度为4,拷贝了3个元素,但是我们可以看到新切片最后有一个空格,是第3和第4个元素的分隔符,只是第四个元素为空
- 示例2 (新切片长度 < 原切片长度)
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| names2 := make([]string,2,4) |
| num := copy(names2,names) |
| fmt.Printf("==================\n新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2)) |
| fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| } |
| 原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
| ================== |
| 新切片:[刘备 关羽] |
| 拷贝了2个元素 |
| 长度为:2 |
| 容量为:4 |
| ================== |
| 再次打印原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
- 示例2 (新切未初始化)
新切片未初始化的结果类似于初始化长度为0的切片
| package main |
| |
| import "fmt" |
| |
| func main() { |
| names := []string{"刘备","关羽","张飞"} |
| fmt.Printf("原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| |
| var names2 []string |
| if names2 == nil{ |
| fmt.Println("==================\nnames2 为空") |
| }else{ |
| fmt.Println("==================\nname2 不为空") |
| } |
| num := copy(names2,names) |
| fmt.Printf("新切片:%+v\n拷贝了%d个元素\n长度为:%d\n容量为:%d\n",names2,num,len(names2),cap(names2)) |
| fmt.Printf("==================\n再次打印原切片:%+v\n长度为:%d\n容量为:%d\n",names,len(names),cap(names)) |
| } |
| 原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |
| ================== |
| names2 为空 |
| 新切片:[] |
| 拷贝了0个元素 |
| 长度为:0 |
| 容量为:0 |
| ================== |
| 再次打印原切片:[刘备 关羽 张飞] |
| 长度为:3 |
| 容量为:3 |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具