数组
数组的长度也是类型的一部分
数组元素类型相同但是长度不同的两个数组认为类型不同
数组初始化后默认值是零值
数组元素类型前的方括号不能为空
要么指定大小 要么用...填充从而实现自动计算长度
数组变量相等意味着除了类型相同之外 所有的元素以及其索引相同
//数组的长度也是类型的一部分
var nums0 [10]int
var nums1 [100]int
fmt.Printf("nums0:%T\n", nums0)
fmt.Printf("nums1:%T\n", nums1)
//数组默认初始化为零值
fmt.Println("nums0", nums0)
//数组元素初始化 使用大括号
//只有前两个元素被赋值
var nums2 = [10]int{10, 20}
fmt.Println("nums2", nums2)
//指定位置赋值 索引:数值
var nums3 = [10]int{0: 10, 9: 20}
fmt.Println("nums3", nums3)
//中括号内填写省略号 自动推导个数
nums4 := [...]int{1, 2, 3}
fmt.Println("nums4", nums4)
//相同类型的数组变量可以相互赋值
nums2, nums3 = nums3, nums2
fmt.Println("nums2:", nums2)
fmt.Println("nums3:", nums3)
//Go语言中数组变量相等意味着所有元素相等
nums5 := [3]int{1, 2, 3}
nums6 := [3]int{1, 2, 3}
nums7 := [3]int{2, 3, 4}
fmt.Println(nums5 == nums6)
fmt.Println(nums5 == nums7)
//获取数组长度 数组的长度在定义后不能改变
fmt.Println(len(nums7))
//数组的遍历
for index, value := range nums3 {
fmt.Println(index, value)
}
//二维数组的遍历
matrix := [3][2]int{{1, 2}, {3, 4}, {5, 6}}
fmt.Printf("%#v\n", matrix)
for _, v := range matrix {
for _, vv := range v {
fmt.Print(vv, " ")
}
fmt.Println()
}
切片
数组的切片操作
中括号内没长度(也没有省略号) 表示是切片类型
[起始位置(闭区间):终止位置(开区间):切片容量]
切片容量大于等于终止位置默认情况下切片容量等于终止位置-起始位置
make函数创建切片
make函数在底层会先初始化一个数组 数组长度为容量(第三个参数)
第一个参数指定切片的类型
第二个参数指定切片的长度
第三个参数指定切片的容量(也可以不指出)切片增加元素 append函数 如果存不下 会创建新的数组空间
因此需要接收返回值(新的数组地址)
切片是传递引用 在内存上对应同一片区域
当某一个切片的操作 引起内存中数组的容量不足时
会重新申请新数组空间 不同切片之间的引用关系消失可以用切片模拟栈、队列这样的数据结构
在使用等号赋值时 数组传递值 切片传递引用
//数组的切片操作
//中括号内没长度(也没有省略号) 表示是切片类型
//起始位置(闭区间):终止位置(开区间):切片容量
//终止位置<=切片容量 默认切片容量等于终止位置-起始位置
fmt.Println(nums3[0:2:2])
fmt.Println(nums3[0:2:5])
//创建一个切片变量
var slice0 []int
fmt.Printf("%T\n", slice0)
fmt.Println(slice0 == nil)
//获取切片的长度和容量
fmt.Printf("%#v %d %d\n", slice0, len(slice0), cap(slice0))
slice0 = []int{1, 2, 3, 4, 5}
//获取切片的长度和容量
fmt.Printf("%#v %d %d\n", slice0, len(slice0), cap(slice0))
//make函数创建切片 make函数在底层会先初始化一个数组 数组长度为容量(第三个参数)
//第一个参数指定切片的类型
//第二个参数指定切片的长度
//第三个参数指定切片的容量
slice1 := make([]int, 3)
fmt.Printf("%#v %d %d\n", slice1, len(slice1), cap(slice1))
slice2 := make([]int, 3, 5)
fmt.Printf("%#v %d %d\n", slice2, len(slice2), cap(slice2))
//切片增加元素 append函数 如果存不下 会创建新的数组空间 因此需要接收返回值(新的数组地址)
slice1 = append(slice1, 1)
fmt.Printf("%#v %d %d\n", slice1, len(slice1), cap(slice1))
//切片是传递引用 在内存上对应同一片区域
//不同切片之间的操作可能引起相互覆盖
slice3 := slice0[1:5]
fmt.Println("slice3:", slice3, "slice0:", slice0)
slice3[0] = 999
slice3[1] = 999
fmt.Println("slice3:", slice3, "slice0:", slice0)
//当某一个切片的操作 引起内存中数组的容量不足时
//会重新申请新数组空间 不同切片之间的引用关系消失
slice3 = append(slice3, 5201314)
fmt.Println("slice3:", slice3, "slice0:", slice0)
//相互影响的效果消失
slice3[0] = 0
fmt.Println("slice3:", slice3, "slice0:", slice0)
//切片的copy函数
sliceCopy0 := make([]int, 3, 5)
sliceCopy0 = []int{1, 2, 3}
sliceCopy1 := []int{10, 20, 30, 40, 50}
copy(sliceCopy0, sliceCopy1)
//超出长度的不复制
fmt.Println("sliceCopy0:", sliceCopy0, "sliceCopy1:", sliceCopy1)
//删除索引为2的元素
copy(sliceCopy1[2:], sliceCopy1[3:])
fmt.Println(sliceCopy1)
//去除最后一个元素
fmt.Println(sliceCopy1[:len(sliceCopy1)-1])
//切片模拟队列
var queue []int
queue = append(queue, 1)
queue = append(queue, 2)
queue = append(queue, 3)
fmt.Println(queue)
//切片模拟栈
var stack []int
stack = append(stack, 1)
stack = append(stack, 2)
stack = append(stack, 3)
//输出栈顶元素
fmt.Println(stack[len(stack)-1])
//弹出栈顶元素 再输出
stack = stack[:len(stack)-1]
fmt.Println(stack[len(stack)-1])
//数组在赋值时是值类型
arrayTest0 := [...]int{1, 2, 3}
arrayTest1 := arrayTest0
arrayTest1[0] = 999
fmt.Println(arrayTest0, arrayTest1)
//切片在赋值时是引用类型
sliceTest0 := []int{1, 2, 3}
sliceTest1 := sliceTest0
sliceTest1[0] = 999
fmt.Println(sliceTest0, sliceTest1)
//对切片进行简单排序 需要明确待排序元素的类型
numsSort := []int{1, 3, 2, 4, 5}
sort.Ints(numsSort)
fmt.Println(numsSort)
namesSort := []string{"hello", "test", "123", "abc"}
sort.Strings(namesSort)
fmt.Println(namesSort)
//nil切片与空切片
//var nums []int{} 切片底层的数组中没有存储元素
//var nums []int 切片底层的数组指针指向nil
映射
映射 也称为 map 字典 hashtable
特点 多组key-value 的结构
map[A]B 索引是A类型 值是B类型当查询不到key值时(key值不存在)返回零值
不能通过是否返回零值判断key值是否存在
应当通过分析返回的第二个参数判断key值是否存在
//映射 map 字典 hashtable
//特点 多组key-value 的结构
//map[A]B 索引是A类型 值是B类型
var scores map[string]int
fmt.Printf("%T %#v\n", scores, scores)
scores = map[string]int{"zpz": 99, "lh": 99}
fmt.Println(scores)
//查值
fmt.Println(scores["zpz"])
//当key不存在时 返回对应类型的零值
fmt.Println(scores["hello"])
//不能通过比较value是否等于零值判断key是否存在
//应该通过第二个返回值判断key是否存在
value, ifExist := scores["hello"]
fmt.Println(value, ifExist)
//遍历 遍历的顺序与添加数据的顺序无关
for key, value := range scores {
fmt.Println(key, value)
}
//删值
delete(scores, "zpz")
fmt.Println(scores)
//多重映射
var users map[string]map[string]string
users = map[string]map[string]string{"zpz": {"1": "a", "2": "b"}, "lh": {"3": "c", "4": "d"}}
fmt.Println(users)
users["zpz"]["1"] = "999"
fmt.Println(users)