切片
-
-
切片:具有可变长度相同类型元素序列.
-
由于长度是可变,可以解决数组长度在数据个数不确定情况下浪费内存的问题.
-
var slice []string //切片 var array [3]string //数组
var slice []string //切片 fmt.Println(slice==nil)//输出:true fmt.Printf("%p",slice)//输出:0x0
定义切片
-
通过直接指定初始值定初始化一个切片变量
names := []string{"smallming", "abcd"} fmt.Println(names)
切片是引用类型
-
引用类型在变量之间赋值时传递的是地址.引用类型变量就是这个类型的指针.切片就是引用类型
-
值类型在变量之间赋值时传递的是值的副本
names := []string{"smallming", "abcd"} names1 := names names1[0] = "efg" fmt.Println(names, names1) fmt.Printf("%p %p",names,names1)//地址相同
-
-
使用make函数定义无内容,但是不是nil的切片,意味着切片已经申请了内存空间
-
make(类型,初始长度[,初始容量])
-
-
slice := make([]string, 0) //长度为0的切片,没有第三个参数表示容量和长度相等 slice1 := make([]string, 0, 2) //长度为0,容量为2 fmt.Println(slice, slice1)
-
-
len(slice) 查看切片的长度
-
-
slice := make([]string, 0) //长度为0的切片,没有第三个参数表示容量和长度相等 slice1 := make([]string, 0, 3) //长度为0,容量为3 fmt.Println(len(slice), cap(slice)) fmt.Println(len(slice1), cap(slice1))
s := make([]string, 0) fmt.Println(len(s), cap(s))//输出:0 0 s = append(s, "1", "2") fmt.Println(len(s), cap(s))//输出:2 2 s = append(s, "smallming") fmt.Println(len(s), cap(s))//输出:3 4
- 如果添加一次添加多个值,且添加后的长度大于扩容一次的大小,容量和长度相等.等到下次添加内容时如果不超出扩容大小,在现在的基础上进行翻倍
s := make([]string, 0) fmt.Println(len(s), cap(s)) //输出:0 0 s = append(s, "1", "2") fmt.Println(len(s), cap(s)) //输出:2 2 s = append(s, "smallming") fmt.Println(len(s), cap(s)) //输出:3 4 s = append(s, "4", "5", "6", "7", "8", "9") fmt.Println(len(s), cap(s)) //输出:9 9 s = append(s,"10") fmt.Println(len(s), cap(s)) //输出:10 18
- 也可以把一个切片的内容直接添加到另一个切片中.需要注意语法中有三个点
s := make([]string, 0) s1 := []string{"smallming", "123"} s = append(s, s1...) //注意此处,必须有三个点 fmt.Println(s)
通过数组产生切片
-
定义数组后,取出数组中一个片段,这个片段就是切片类型
names := [3]string{"a", "b", "c"} s := names[0:2] //包前不包后 fmt.Printf("%T", s) //输出:[]string fmt.Println(s) //输出:[a b]
- 切片是指针,指向数组元素地址,修改切片的内容,数组的内容会跟随变化
names := [3]string{"a", "b", "c"} s := names[0:2] //包前不包后 fmt.Printf("%p %p",s,&names[0])//输出的地址是相同的 s[0] = "Go语言" fmt.Println(s) //输出:[Go语言 b] fmt.Println(names) //输出:[Go语言 b c]
-
-
如果增加后切片的长度没有超出数组,修改切片也是在修改数组
-
如果增加后切片的长度超出数组,会重新开辟一块空间放切片的内容
-
-
names := [3]string{"a", "b", "smallming"} s := names[0:2] //包前不包后 fmt.Printf("%p %p\n",s,&names[0]) s[0] = "Go语言" s=append(s,"区块链") fmt.Println(s) //输出:[Go语言 b 区块链] fmt.Println(names) //输出:[Go语言 b 区块链] fmt.Printf("%p %p\n",s,&names[0])//地址相同 s=append(s,"超出了数组长度") fmt.Println(s) //输出:[Go语言 b 区块链 超出了数组长度] fmt.Println(names) //输出:[Go语言 b 区块链] fmt.Printf("%p %p\n",s,&names[0])//切片地址改变
删除实现
-
Go语言标准库中没有提供删除的函数
-
切片也可以取其中的一段形成子切片,利用这个特性可以实现删除效果
num := []int {0,1,2,3,4,5,6} //要删除脚标为n的元素 n:= 2 num1 :=num[0:n] num1= append(num1,num[n+1:]...) fmt.Println(num1)
copy函数
-
通过copy函数可以把一个切片内容复制到另一个切片中
-
Go语言标准库源码定义如下
-
第一个参数是目标切片,接收第二个参数内容
-
第二个参数是源切片,把内容拷贝到第一个参数中
-
// The copy built-in function copies elements from a source slice into a // destination slice. (As a special case, it also will copy bytes from a // string to a slice of bytes.) The source and destination may overlap. Copy // returns the number of elements copied, which will be the minimum of // len(src) and len(dst). func copy(dst, src []Type) int
- 拷贝时严格按照脚标进行拷贝.且不会对目标切片进行扩容
-
把短切片拷贝到长切片中
s1:=[]int {1,2} s2:=[]int {3,4,5,6} copy(s2,s1) fmt.Println(s1)//输出:[1 2] fmt.Println(s2)//输出:[1 2 5 6]
- 把长切片拷贝到短切片中
s1:=[]int {1,2} s2:=[]int {3,4,5,6} copy(s1,s2) fmt.Println(s1)//输出:[3 4] fmt.Println(s2)//输出:[3 4 5 6]
- 把切片片段拷贝到切片中
s1:=[]int {1,2} s2:=[]int {3,4,5,6} copy(s1,s2[1:]) fmt.Println(s1)//输出:[4 5] fmt.Println(s2)//输出:[3 4 5 6]
使用copy完成删除元素
-
使用copy函数可以保证原切片内容不变
s := []int{1, 2, 3, 4, 5, 6, 7} n := 2 //要删除元素的索引 newSlice := make([]int, n) copy(newSlice, s[0:n]) newSlice = append(newSlice, s[n+1:]...) fmt.Println(s) //原切片不变 fmt.Println(newSlice) //删除指定元素后的切片
sort包
-
Go语言标准库中sort提供了排序API
-
sort包提供了多种排序算法,这些算法是内部实现的,每次使用sort包排序时,会自动选择最优算法实现
-
插入排序
-
快速排序
-
堆排
-
-
// A type, typically a collection, that satisfies sort.Interface can be // sorted by the routines in this package. The methods require that the // elements of the collection be enumerated by an integer index. type Interface interface { // Len is the number of elements in the collection. Len() int // Less reports whether the element with // index i should sort before the element with index j. Less(i, j int) bool // Swap swaps the elements with indexes i and j. Swap(i, j int) }
-
对int类型切片排序
num := [] int{1, 7, 5, 2, 6} sort.Ints(num) //升序 fmt.Println(num) sort.Sort(sort.Reverse(sort.IntSlice(num))) //降序 fmt.Println(num)
- 对float64类型切片排序
f := [] float64{1.5, 7.2, 5.8, 2.3, 6.9} sort.Float64s(f) //升序 fmt.Println(f) sort.Sort(sort.Reverse(sort.Float64Slice(f))) //降序 fmt.Println(f)
-
-
按照编码表数值进行排序
-
多字符串中按照第一个字符进行比较
-
-
s := []string{"我", "我是中国人", "a", "d", "国家", "你", "我a"} sort.Sort(sort.StringSlice(s)) //升序 fmt.Println(s) //查找内容的索引,如果不存在,返回内容应该在升序排序切片的哪个位置插入 fmt.Println(sort.SearchStrings(s, "你是")) sort.Sort(sort.Reverse(sort.StringSlice(s))) fmt.Println(s)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人