切片是一个拥有相同类型元素的可变长度的序列,底层基于数组类型进行封装。
切片是一个引用类型,内部结构包括地址
(切片中第一元素的指向的内存空间)、大小
(切片中目前元素的个数)和容量
(底层数组最大能存放的元素个数),必须初始化才能使用。
值类型,整型、浮点型、布尔型、字符串、数组,声明时就有初始值。
引用类型,声明时候的初始值是nil。nil在内存中是没有位置。
var 变量名 []变量类型
切片使用
func main() {
// 直接声明使用
var a = []int{1, 2, 3}
fmt.Println(a) //[1 2 3]
fmt.Println(a[1]) //2
fmt.Printf("a:%T\n", a) //a:[]int
//从数组中得到切片
var b = [10]int{1, 2, 3, 4, 5}
var c = b[1:6]
fmt.Println(c) // [2 3 4 5 0]
//切片大小(目前元素的梳理)
fmt.Printf("切片大小:%d\n", len(c)) //5
//切片容量(底层数据组最大能放多少元素)
fmt.Printf("切片容量:%d\n", cap(c)) //9
//切片再切片,不可超容量
var d = c[1:6]
fmt.Println(d)
}
切片扩容
func main() {
//切片扩容,扩容策略,每一次都是上一次的2倍
var e = []int{}
fmt.Println(e, len(e), cap(e)) //[] 0 0
e = append(e, 1)
fmt.Println(e, len(e), cap(e)) //[1] 1 1
e = append(e, 1)
fmt.Println(e, len(e), cap(e)) //[1 1] 2 2
e = append(e, 1)
fmt.Println(e, len(e), cap(e)) //[1 1 1] 3 4
e = append(e, 1)
fmt.Println(e, len(e), cap(e)) //[1 1 1 1] 4 4
}
注意:
(1)切片支持 自动扩容
,扩容策略每一次都是上一次的2倍
。(扩容策略源码在$GOROOT/src/runtime/slice.go)
(2)append()是内置函数,往切片中追加元素。
slice = append(slice, e)
切片是引用类型
func main() {
//验证切片是引用类型
var a = []int{1, 2, 3}
fmt.Println(a) //[1 2 3]
b := a
b[0] = 11
fmt.Println(a) //[11 2 3]
fmt.Println(b) //[11 2 3]
}
切片复制copy
函数
func main() {
var a = []int{1, 2, 3}
//切片复制copy
// var c []int //未申请内存
// c = make([]int, 3, 3) //申请内存
//或者声明初始化,也申请内存
c := []int{0, 0, 0}
count := copy(c, a)
fmt.Println(count) //3
fmt.Println(c) //[11 2 3]
c[1] = 22
fmt.Println(c) //[11 22 3]
fmt.Println(a) //[11 2 3]
}
切片中元素删除
append
函数中,...
把切片中拆成一个一个元素
func main() {
//从切片中删除元素
d := []int{1, 2, 3, 4, 5}
fmt.Println(d) //[1 2 3 4 5]
//...把切片中拆成一个一个元素
d = append(d[:1], d[2:]...)
fmt.Println(d) //[1 3 4 5]
}
切片不能直接比较,只能和nil
比较。一个nil
值切片底层没有数组,nil
值切片长度0。
func main(){
//只声明
var a []int
fmt.Println(a, len(a), cap(a)) //[] 0 0
if a == nil {
fmt.Println("a is nil") //a is nil
}
//声明并且初始化
b := []int{}
fmt.Println(b, len(b), cap(b)) //[] 0 0
if b == nil {
fmt.Println("b is nil")
}
c := make([]int, 0) //[] 0 0
fmt.Println(c, len(c), cap(c))
if c == nil {
fmt.Println("c is nil")
}
//判断切片是否空,不能用nil,需要用len函数
if len(a) == 0 {
fmt.Println("a 是空切片")
}
if len(b) == 0 {
fmt.Println("b 是空切片")
}
if len(c) == 0 {
fmt.Println("c 是空切片")
}
}
切片遍历
func main() {
// 直接声明使用
var a = []int{1, 2, 3}
fmt.Println(a)
for i := 0; i < len(a); i++ {
fmt.Printf("a[%d]=%d\n", i, a[i])
}
for index, value := range a {
fmt.Printf("a[%d]=%d\n", index, value)
}
}
有疑问加站长微信联系(非本文作者)