切片是长度可变的数组(具有相同数据类型的数据项组成的一组长度可变的序列),切片由三部分组成:
指针:指向切片第一个元素指向的数组元素的地址
长度:切片元素的数量
容量:切片开始到结束位置元素的数量
切片声明需要指定组成元素的类型,但不需要指定存储元素的数量(长度)。在切片声明后,会被初始化为nil,表示暂不存在的切片。
定义切片
//定义切片
var identifier []type
//使用 make() 函数来创建切片:
var slice1 []type = make([]type, len)
//也可以简写为
slice1 := make([]type, len)
//也可以指定容量,其中 capacity为可选参数。
make([]T, length, capacity) //这里 len 是数组的长度并且也是切片的初始长度。
初始化切片
s := []int{1,2,3} //直接使用字面量初始化切片,[]表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3。
s := []int{} //使用字面量初始化空切片
s := []int{1:1, 3:3, 99:99} //指定长度和容量字面量初始化
s := arr[:] //初始化切片s,是数组arr的引用。
s := arr[startIndex:endIndex] //将arr中从下标startIndex到endIndex-1下的元素创建为一个新的切片。
s := arr[startIndex:endIndex:cap] //注意end<=cap<=len
s := arr[startIndex:] //默认endIndex时将表示一直到arr的最后一个元素。
s := arr[:endIndex] //默认startIndex时将表示从arr的第一个元素开始。
s1 := s[startIndex:endIndex] //通过切片s初始化切片s1。
s := make([]int,len,cap) //通过make函数创建长度为len,容量为cap的切片,len必须小于等于cap。cap可以省略。
len() 和 cap() 函数
切片是可索引的,可以使用len()函数可获取切片的长度,使用cap()函数可获取切片容量
空(nil)切片 一个切片在未初始化之前默认为 nil,长度为 0。
package main
import "fmt"
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
func main() {
var s []int
if s == nil {
fmt.Printf("切片是空的\n")
}
var numbers = make([]int, 3, 5)
printSlice(numbers)
}
切片截取
可以通过设置下限及上限来设置截取切片 [lower-bound:upper-bound]
package main
import "fmt"
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
func main() {
/* 创建切片 */
numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
printSlice(numbers)
/* 打印原始切片 */
fmt.Println("numbers ==", numbers)
/* 打印子切片从索引1(包含) 到索引4(不包含)*/
fmt.Println("numbers[1:4] ==", numbers[1:4])
/* 默认下限为 0*/
fmt.Println("numbers[:3] ==", numbers[:3])
/* 默认上限为 len(s)*/
fmt.Println("numbers[4:] ==", numbers[4:])
numbers1 := make([]int, 0, 5)
printSlice(numbers1)
/* 打印子切片从索引 0(包含) 到索引 2(不包含) */
number2 := numbers[:2]
printSlice(number2)
/* 打印子切片从索引 2(包含) 到索引 5(不包含) */
number3 := numbers[2:5]
printSlice(number3)
}
append() 和 copy() 函数
如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来。
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
/* 允许追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers)
/* 向切片添加一个元素 */
numbers = append(numbers, 1)
printSlice(numbers)
/* 同时添加多个元素 */
numbers = append(numbers, 2, 3, 4)
printSlice(numbers)
/* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2)
/* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1, numbers)
printSlice(numbers1)
}
func printSlice(x []int) {
fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
练习:
package main
import "fmt"
func main() {
//切片: 长度可变的数组
/*
切片由三部分组成:
指针: 指向切片第一个元素指向的数组元素的地址
长度: 切片元素的数量
容量: 切片开始到结束位置元素的数量
*/
//切片声明需要指定组成元素的类型,但不需要指定存储元素的数量(长度)。
//切片声明后,会被初始化为nil,表示暂不存在的切片
var sliceint []int
fmt.Printf("%T %t %v\n", sliceint, sliceint == nil, sliceint)
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
//字面量
sliceint = []int{1, 2, 3}
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
fmt.Println(sliceint)
sliceint = []int{1, 2, 3, 4}
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
fmt.Println(sliceint)
// 通过数组切片赋值
var arrayint [10]int = [10]int{1, 2, 3, 4, 5, 6}
sliceint = arrayint[1:10]
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
fmt.Println(sliceint)
//获取切片的长度 len()
//获取切片的容量 cap()
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
//make函数 会对指针进行初始化
sliceint = make([]int, 3)
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
sliceint = make([]int, 3, 5)
fmt.Printf("%#v %d %d\n", sliceint, len(sliceint), cap(sliceint))
//元素操作(增删改查)
fmt.Println(sliceint[0])
fmt.Println(sliceint[1])
fmt.Println(sliceint[2])
//fmt.Println(sliceint[3])
//fmt.Println(sliceint[4])
sliceint[2] = 10
fmt.Println(sliceint)
sliceint = append(sliceint, 3)
fmt.Println(sliceint)
for i := 0; i <= len(sliceint)-1; i++ {
fmt.Println(sliceint[i])
}
for i, v := range sliceint {
fmt.Println(i, v)
}
//切片操作
fmt.Printf("%T %v\n", sliceint[1:5], sliceint[1:5])
sliceint = make([]int, 3, 10)
fmt.Printf("%T %d %d\n", sliceint, len(sliceint), cap(sliceint))
//s_cap - start
//len - start
s := sliceint[1:3:9]
fmt.Printf("%T %d %d\n", s, len(s), cap(s))
//src_cap - start
s1 := sliceint[4:6]
fmt.Printf("%T %d %d\n", s1, len(s1), cap(s1))
//切片的切片,底层是共用指针地址
sliceint = make([]int, 3, 5)
sliceint2 := sliceint[1:3]
fmt.Println(sliceint, sliceint2)
sliceint2[0] = 1
fmt.Println(sliceint, sliceint2)
sliceint2 = append(sliceint2, 4)
fmt.Println(sliceint, sliceint2)
sliceint = append(sliceint, 5)
fmt.Println(sliceint, sliceint2)
sliceint = arrayint[:]
fmt.Println(sliceint, arrayint)
sliceint[0] = 100
fmt.Println(sliceint, arrayint)
//删除
//copy
sliceint001 := []int{1, 2, 3}
sliceint002 := []int{10, 20, 30, 40}
copy(sliceint002, sliceint001)
fmt.Println(sliceint001, sliceint002)
sliceint002 = []int{10, 20, 30, 40}
copy(sliceint001, sliceint002)
fmt.Println(sliceint001, sliceint002)
//删除索引为0,索引1
sliceint003 := []int{1, 2, 3, 4, 5}
fmt.Println(sliceint003[1:])
fmt.Println(sliceint003[:len(sliceint003)-1])
//删除中间的元素2(3)
copy(sliceint003[2:], sliceint003[3:])
fmt.Println(sliceint003[:len(sliceint003)-1])
//堆栈,队列
//队列: 每次添加在队尾,移除元素在队头
//堆栈: 每次添加在队尾,移除元素在队尾
//队列
queue := []int{}
queue = append(queue, 1)
queue = append(queue, 2)
queue = append(queue, 3)
queue = append(queue, 4)
//1,2,3,4
fmt.Println(queue)
//2,3,4
queue = queue[1:]
fmt.Println(queue)
//3,4
queue = queue[1:]
fmt.Println(queue)
//堆栈
stack := []int{}
stack = append(stack, 1)
stack = append(stack, 2)
stack = append(stack, 3)
stack = append(stack, 4)
//1,2,3,4
fmt.Println(stack)
//1,2,3
stack = stack[:len(stack)-1]
fmt.Println(stack)
//1,2
stack = stack[:len(stack)-1]
fmt.Println(stack)
}
多维切片
package main
import "fmt"
func main() {
//定义多维切片
var mslice [][]int
//mslice := make([][]int, 0)
mslice = append(mslice, []int{1, 2, 3})
mslice = append(mslice, []int{3, 4, 0})
fmt.Println(mslice)
//切片的切片操作
fmt.Println(mslice[0])
fmt.Println(mslice[0][1])
}