Golang之切片

切片

切片是长度可变的数组,由三部分组成:指针、长度、容量

指针:指向切片第一个元素的地址

长度:切片元素的数量

容量:切片开始到结束元素的数量

声明

切片声明需要指定组成元素的类型,但不需要指定存储元素的数量(长度),切片会被初始化为nil,表示不存在的切片

package main

import "fmt"

func main() {
	var names []string
	// %t 比较条件输出true false
	fmt.Printf("%T, %t, %#V\n", names, names == nil, names)
}

结果:

go run blog.go            
[]string, true, []

初始化

package main

func main() {
	//使用字面量初始化:[]type{v1, v2, …, vn}
	var num0 []int = []int{1, 2, 3}
	//使用字面量初始化空切片: []type{}
	var num1 []int = []int{}
	//使用 make 函数初始化
	//make([]type, len)/make([]type, len, cap),
	//通过 make 函数创建长度为 len,容量 为 cap 的切片,len 必须小于等于 cap
	var num1 []int = make([]int, 3, 5)
}

操作

package main

import "fmt"

func main() {
	// 获取切片长度(len)和容量(cap)
	students := []string{"张三", "李四"}
	students1 := make([]string, 3, 10)
	fmt.Println(len(students), cap(students))
	fmt.Println(len(students1), cap(students1))
	/*
		结果
		2 2
		3 10

	*/
	// 访问和修改
	// fmt.Print(students[0])
	students[0] = "小组"
	fmt.Printf("%#v\n", students)
	// 切片: slice[start:end] 用于生成一个新的切片
	teachers := []string{"a", "b", "c", "d", "e"}
	teachers1 := teachers[:]
	teachers2 := teachers[0:2]
	teachers3 := teachers1[1:4]

	fmt.Printf("%#v\n", teachers)
	fmt.Printf("%#v\n", teachers1)
	fmt.Printf("%#v\n", teachers2)
	fmt.Printf("%#v\n", teachers3)

	/*
		结果
		[]string{"a", "b", "c", "d", "e"}
		[]string{"a", "b", "c", "d", "e"}
		[]string{"a", "b"}
		[]string{"b", "c", "d"}
	*/
	// 新建切片长度和容量计算:len:end-start   cap:之前的cap - start
	// 切片共享底层数组,若某个切片元素发生变化,其他切片也会发生改变

	teachers[1] = "abc"
	fmt.Printf("%#v\n", teachers)
	fmt.Printf("%#v\n", teachers1)
	fmt.Printf("%#v\n", teachers2)
	fmt.Printf("%#v\n", teachers3)

	/*
		结果
			[]string{"a", "abc", "c", "d", "e"}
			[]string{"a", "abc", "c", "d", "e"}
			[]string{"a", "abc"}
			[]string{"abc", "c", "d"}
	*/
	//slice[start:end:cap]可用于限制新切片的容量值,end<=cap<=之前的cap
	//新建切片长度和容量计算:len:end-start,cap:cap-start

	// 遍历,可以通过for len和for range对切片元素进行遍历
	for i := 0; i < len(teachers); i++ {
		fmt.Printf("%d, %#v\n", i, teachers[i])
	}

	for i, v := range teachers {
		fmt.Printf("%d, %#v\n", i, v)
	}

	/*
	结果
	0, "a"
	1, "abc"
	2, "c"
	3, "d"
	4, "e"
	*/

	//增加元素
	// 使用 append 对切片增加一个或多个元素并返回修改后切片,
	// 当新切片长度在容量范围内时只能增加长度,容量和底层数组不变
	// 当超过容量就会创建一个新的底层数组并对容量进行只能运算
	//(元素数量<1024 时,约按原容量 1 倍增加,>1024 时约按原容量 0. 倍增加)
	
}