golang的复合数据结构包括:数组、切片、结构体、函数、map、channel、接口等
1.数组
1.1数组的初始化
import "fmt"func main() {//数组的初始化1var arr1 [3]intarr1[0] = 1arr1[1] = 2arr1[2] = 3fmt.Println(arr1)//数组的初始化2var arr2 = [4]int{1, 2, 3, 4}fmt.Println(arr2)//数组初始化3,自动判断数组长度var arr3 = [...]int{1, 2}fmt.Println(arr3)//数组初始化4,指定下标arr4 := [...]int{1: 1, 3: 5}fmt.Println(arr4)//数组的类型var arr5 [3]intvar arr6 [4]stringfmt.Printf("%T,%T", arr5, arr6)
}
1.2 数组是值类型,赋值和传参会赋值整个数组,因此改变副本的值,不会改变本身的值
package mainimport "fmt"func main() {var arr1 = [...]int{1, 2, 3}arr2 := arr1arr2[0] = 3fmt.Println(arr1, arr2)
}//[1 2 3] [3 2 3]
2.切片
在golang中,切片的定义和数组定义是相似的,但是需要注意的是,切片是引用数据类型
2.1 切片的引用
package mainimport "fmt"func main() {var arr1 = []int{1, 2, 3}arr2 := arr1arr2[0] = 3fmt.Println(arr1, arr2)
}//[3 2 3] [3 2 3]
2.2 为什么要使用切片
切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做的一层封装。 它非常灵活,支持自动扩容。
切片是一个引用类型,它的内部结构包含地址、长度和容量。
package mainimport "fmt"func main() {//切片的定义var slice = []int{1, 2, 3}fmt.Println(slice)//数组定义切片arr := [5]int{55, 56, 57, 58, 59}a := arr[:]b := arr[1:4]c := arr[:3]d := arr[3:]fmt.Println(a)fmt.Println(b)fmt.Println(c)fmt.Println(d)
}
2.3 切片的长度和容量
切片拥有自己的长度和容量,我们可以通过使用内置的len()函数求长度,使用内置的cap() 函数求切片的容量。
切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。切片s的长度和容量可通过表达式len(s)和cap(s)来获取。
import "fmt"func main() {// 长度和容量arr1 := []int{1, 2, 3, 4, 5, 6}fmt.Printf("长度%d 容量%d\n", len(arr1), cap(arr1))arr2 := arr1[2:]fmt.Printf("长度%d 容量%d\n", len(arr2), cap(arr2))arr3 := arr1[2:4]fmt.Printf("长度%d 容量%d\n", len(arr3), cap(arr3))}
2.4 切片的本质
切片的本质就是对与数组的特殊封装,它包含了三个信息:
底层数组的指针
切片的长度
切片的容量
2.5 使用make函数创造切片
func main() {// make()函数创建切片var slices = make([]int, 4, 8)//[0 0 0 0]fmt.Println(slices)// 长度:4, 容量8fmt.Printf("长度:%d, 容量%d", len(slices), cap(slices))}
2.6 golang中没办法通过下标来给切片扩容,如果需要扩容,需要用到append
package mainimport "fmt"func main() {//切片的扩容slices2 := []int{1, 2, 3, 4}slices2 = append(slices2, 5)fmt.Println(slices2)// 输出结果 [1 2 3 4 5]//切片的合并// 合并切片slices3 := []int{6, 7, 8}slices2 = append(slices2, slices3...)fmt.Println(slices2)// 输出结果 [1 2 3 4 5 6 7 8]//使用copy复制切片//前面我们知道,切片就是引用数据类型//值类型:改变变量副本的时候,不会改变变量本身//引用类型:改变变量副本值的时候,会改变变量本身的值//如果我们需要改变切片的值,同时又不想影响到原来的切片,那么就需要用到copy函数// 需要复制的切片var slices4 = []int{1, 2, 3, 4}// 使用make函数创建一个切片var slices5 = make([]int, len(slices4), len(slices4))// 拷贝切片的值copy(slices5, slices4)// 修改切片slices5[0] = 4fmt.Println(slices4)fmt.Println(slices5)//[1 2 3 4]//[4 2 3 4]}
2.7 删除切片中的值
并没有删除切片元素的专用方法,我们可以利用切片本身的特性来删除元素
package mainimport "fmt"func main() {//删除索引为1的元素var slice = []int{1, 2, 3, 4, 5, 6, 7, 8, 9}slice = append(slice[:1], slice[2:]...)fmt.Println(slice)
}
2.8 切片的排序
切片排序第一种就是使用排序算法
第二种就是自带的排序
package mainimport ("fmt""sort"
)func main() {var numslice4 = []int{3, 2, 1, 4, 5, 7, 6}sort.Ints(numslice4)fmt.Println(numslice4)var slice5 = []int{9, 8, 4, 5, 1, 7}sort.Sort(sort.Reverse(sort.IntSlice(slice5)))
}
3. map
map是一种无序的基于key-value的数据结构,Go语言中的map是引用类型,必须初始化才能使用。
3.1 map初始化
ap类型的变量默认初始值为nil
,需要使用make()
函数来分配内存。语法为:
make:用于slice、map和channel的初始化
package main
import "fmt"
func main() {// 方式1初始化var userInfo = make(map[string]string)userInfo["name"] = "xiaohei"userInfo["age"] = "20"userInfo["sex"] = "男"fmt.Println(userInfo)fmt.Println(userInfo["userName"])// 声明式初始化var userInfo2 = map[string]string {"name":"xiaohei","age":"20","sex":"男",}fmt.Println(userInfo2)
}
3.2 map的操作
//遍历mapfor s, s2 := range userInfo {fmt.Println("key:", s, " value:", s2)}//判断某个元素是否存在value, ok := userInfo2["name"]fmt.Println(value, ok)//删除某个元素delete(userInfo2, "sex")fmt.Println(userInfo2)