//slice源码
type slice struct {
array unsafe.Pointer //指向存放数据的数组指针
len int //长度有多大
cap int //容量有多大
}
func main() {
var slice []string //切片
var array [3]string //数组
}
注意:切片只能和nil进行判断是否相等
func main() {
var slice []string //切片
fmt.Println(slice == nil) //输出:true
fmt.Printf("%p", slice) //输出:0x0
}
定义切片
通过直接指定初始值初始化一个切片变量
func main() {
names := []string{"smallming", "little ming"}
fmt.Println(names) //输出:[smallming little ming]
}
定义数组后,取出数组中一个片段,这个片段就是切片类型
func main() {
names := [3]string{"z3", "l4", "w5"}
s := names[0:2] //包前不保后
fmt.Printf("%T", s) //输出:[]string
fmt.Println(s) //输出:[z3 l4]
}
make(类型,初始长度[,初始容量])
长度表示切片中元素的实际个数,容量表示切片占用空间大小,且切片成倍增加,当增加到1024后按照一定百分比增加
len(slice)查看切片的长度
cap(slice)查看切片的容量
func main() {
slice := make([]string, 0) //长度为0的切片,没有第三个参数表示容量和长度和长度相等
slice1 := make([]string, 0, 2) //长度为0,容量为2
fmt.Println(len(slice), cap(slice)) //0 0
fmt.Println(len(slice1), cap(slice1))//0 2
}
切片是引用类型
引用类型在变量之间赋值时传递的是地址,引用类型变量就是这个类型的指针,切片就是引用类型
func main() {
names := []string{"smallming", "littleming"}
names1 := names
names1[0] = "张"
fmt.Println(names, names1) //输出:[张 littleming] [张 littleming]
fmt.Printf("%p %p", names, names1)//地址相同0xc000098420 0xc000098420
}
(1)产生切片
切片的产生,可以详见上面部分《定义切片》内容。以下为一些需要了解的注意事项:
1、如果增加后切片的长度没有超出数组,修改切片也是在修改数组;
2、如果增加后切片的长度超出数组,会重新开辟一块内存空间存放切片的内容;
3、通过下面代码也正面了切片内容中内容存在一块连续空间(和数组一样);
代码示例:
func main() {
names := [3]string{"z3", "l4", "w5"}
s := names[0:2] //包前不保后
fmt.Printf("%p, %p\n", s, &names[0]) //输出内存地址一致:0xc000070330, 0xc000070330
s[0] = "Go语言"
s = append(s, "区块链")
fmt.Println(s) //输出:[Go语言 l4 区块链]
fmt.Println(names) //输出:[Go语言 l4 区块链]
fmt.Printf("%p, %p\n", s, &names[0]) //内存地址相同
s = append(s, "超出了数组长度")
fmt.Println(s)
fmt.Println(names)
fmt.Printf("%p, %p\n", s, &names[0]) //切片内存地址改变:0xc000048060, 0xc000070330
}
大家想进一步了解切片的内存变化,可以看看下面的这篇文章:
(2)删除实现
func main() {
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)
}
(3)append函数,添加实现
func append(slice []Type, elems ...Type) []Type
func main() {
s1 := make([]string, 0)
fmt.Println(len(s1), cap(s1))//0 0
s2 := append(s1, "z3", "test3")
fmt.Println(len(s2), cap(s2))//2 2
s3 := append(s2, "smallming")
fmt.Println(len(s3), cap(s3)) //3 4
}
func main() {
s1 := make([]string, 0)
fmt.Println(len(s1), cap(s1)) //0 0
s2 := append(s1, "z3", "test3")
fmt.Println(len(s2), cap(s2)) //2 2
s3 := append(s2, "smallming")
fmt.Println(len(s3), cap(s3)) //3 4
s4 := append(s3, "4", "5", "6", "7", "8", "9")
fmt.Println(len(s4), cap(s4)) //9 9
fmt.Println(s4) //[z3 test3 smallming 4 5 6 7 8 9] 长度为9,容量为9
s5 := append(s4, "10")
fmt.Println(len(s5), cap(s5)) //10 18 容量在上次9的基础上翻倍
fmt.Println(s5) //[z3 test3 smallming 4 5 6 7 8 9 10]
}
也可以把一个切片的内容之间添加到另一个切片中,需要注意语法中三个点
func main() {
s := make([]string, 0)
s1 := []string{"smallming", "test"}
s = append(s, s1...) //注意此处,必须有三个点
fmt.Println(s) //[smallming test]
}
(4)copy函数,操作切片
第一个参数是目标切片,接收第二个参数内容
第二个参数是源切片,把内容拷贝到第一个参数中
func copy(dst, src []Type) int
func main() {
num1 := []int{0, 1, 2, 3}
num2 := []int{4, 5, 6, 7, 8}
copy(num2, num1)
fmt.Println(num1, num2) //[0 1 2 3] [0 1 2 3 8]
}
func main() {
num1 := []int{0, 1, 2, 3}
num2 := []int{4, 5, 6, 7, 8}
copy(num1, num2)
fmt.Println(num1, num2) //[4 5 6 7] [4 5 6 7 8]
}
func main() {
num1 := []int{0, 1, 2, 3}
num2 := []int{4, 5, 6, 7, 8}
copy(num2, num1[2:])
fmt.Println(num1, num2) //[0 1 2 3] [2 3 6 7 8]
}
func main() {
s := []int {1,2,3,4,5,6,7,8}
n := 2 //要删除元素的索引
newslice := make([]int, n)
copy(newslice, s[0:n])
newslice = append(newslice, s[n 1:]...)
fmt.Println(s) //原切片不变
fmt.Println(newslice) //删除指定元素后的切片
}
(5)sort包操作切片
1、插入排序
2、快速排序
3、堆排
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)
}
排序实现
func main() {
s := []int{1, 7, 6, 9, 8}
sort.Ints(s) //升序
fmt.Println(s) //[1 6 7 8 9]
sort.Sort(sort.Reverse(sort.IntSlice(s))) //降序
fmt.Println(s) //[9 8 7 6 1]
}
func main() {
f := []float64{1.5, 7.2, 5.8, 2.3, 6.8}
sort.Float64s(f) //升序
fmt.Println(f) //[1.5 2.3 5.8 6.8 7.2]
sort.Sort(sort.Reverse(sort.Float64Slice(f))) //降序
fmt.Println(f) //[7.2 6.8 5.8 2.3 1.5]
}
1、按照编码表数值进行排序
2、多字符串中按照第一个字符进行比较
3、如果第一个字符相同,比较第二个字符
func main() {
s := []string{"我", "我是中国人", "a", "d", "国家", "你", "我a"}
sort.Sort(sort.StringSlice(s))
fmt.Println(s) //升序:[a d 你 国家 我 我a 我是中国人]
//查找内容的索引,如果不存在,返回内容应该在升序排序切片的哪个位置插入
fmt.Println(sort.SearchStrings(s, "你是")) //输出:3
sort.Sort(sort.Reverse(sort.StringSlice(s)))
fmt.Println(s) //[我是中国人 我a 我 国家 你 d a]
}
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved