概念
Go 语言切片是对数组的抽象。
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
package main
import "fmt"
func main() {
// 定义并初始化
s := []int{1,2,3}
fmt.Println(s)
// 切片的定义
var names []string
// nil 类似于其他语言中的空
fmt.Println(names == nil) //true
// 初始化
names = []string{"jack", "tom", "rose", "jerry"}
fmt.Println(names)
// 长度和容量
fmt.Println(len(names))
fmt.Println(cap(names))
// 由数组得到切片
a1 := [...]int{1, 2, 3, 4, 5}
a2 := a1[1:3]
a3 := a1[:3]
a4 := a1[1:]
a5 := a1[:]
fmt.Println(a1, a2)
// 由数组得到的切片的长度和容量
fmt.Println(len(a2), cap(a2)) // 2,4
fmt.Println(len(a3), cap(a3)) //3,5
fmt.Println(len(a4), cap(a4)) //4,4
fmt.Println(len(a5), cap(a5)) // 5,5
}
使用make函数创建切片
package main
import "fmt"
func main(){
// 可以使用make函数指定切片的容量和长度
s := make([] int, 5,10)
fmt.Println(s,len(s),cap(s))
}
切片的本质
切片的本质就是对底层数组的封装,它包含了三个信息:底层数组的指针、切片的长度(len)和切片的容量(cap)。切片之间是不能比较的,我们不能使用==操作符来判断两个切片是否含有全部相等元素。 切片唯一合法的比较操作是和nil比较。 一个nil值的切片并没有底层数组,一个nil值的切片的长度和容量都是0。但是我们不能说一个长度和容量都是0的切片一定是nil
package main
import "fmt"
func main() {
// s1 := make([]int, 0)
// s2 := []int{}
// slice can only be compared to nil
// fmt.Println(s1 == s2)
// fmt.Println(s1 == nil) //false
var s1[] int
fmt.Println(s1 == nil) //true
}
切片的拷贝赋值
package main
import "fmt"
func main(){
s1 := []int{1,2,3}
s2 := s1 //指向同一块内存空间
s1[1] = 111
fmt.Println(s1,s2)
// 还可以使用copy函数来赋值切片
a := []int{1, 2, 3, 4, 5}
c := make([]int, 5, 5)
// c:数据来源切片和目标切片
copy(c, a) //使用copy()函数将切片a中的元素复制到切片c
fmt.Println(a) //[1 2 3 4 5]
fmt.Println(c) //[1 2 3 4 5]
c[0] = 1000
fmt.Println(a) //[1 2 3 4 5]
fmt.Println(c) //[1000 2 3 4 5]
}
切片的遍历
func main() {
s := []int{1, 3, 5}
for i := 0; i < len(s); i++ {
fmt.Println(i, s[i])
}
for index, value := range s {
fmt.Println(index, value)
}
}
切片的新增、删除和扩容
Go语言的内建函数append()可以为切片动态添加元素,每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()函数调用时,所以我们通常都需要用原变量接收append函数的返回值。
package main
import "fmt"
func main(){
s1 := make([]int,2,3)
s1[0] = 0
s1[1] = 1
// s1[2] = 2 //index out of range [2] with length 2
// 使用append函数向切片中增加 如果长度、容量不够会自动扩容
// 使用append函数,必须使用元切片接受返回值
s1 = append(s1,2)
fmt.Println(s1)
// go语言中没有提供切片的删除方法,我们可以使用append来模拟切片的删除操作
// 从切片中删除元素
a := []int{30, 31, 32, 33, 34, 35, 36, 37}
// 要删除索引为2的元素
a = append(a[:2], a[3:]...)
fmt.Println(a) //[30 31 33 34 35 36 37]
ss1 := []int{1,2,3}
ss2 := []int{11,22}
// ss2... 将切片展开
ss1 = append(ss1,ss2...)
fmt.Printf("%v,%d,%d",ss1,len(ss1),cap(ss1))
}