golang数组&切片&map

数组

数组声明
go 复制代码
func main() {

	/* 语法一 */
  // 数组名字 [数组长度] 数组类型
	// 声明一个数组 长度为3 类型是int 会初始化为int类型的零值,默认值是[0 0 0 ]
	// 声明数组的时候指定长度是一个常量,数组的不可改变,超出长度会报错
	var arr [3]int
	// 数组赋值
	arr[0] = 1
	arr[1] = 2
	fmt.Println(arr) // [1 2 0]

	/* 语法二 声明数组同时赋值, 指定的长度为4,指定值初始化数组,默认为「1 2 0 0】*/
	var arr2 = [4]int{1, 2}
	fmt.Println(arr2)
	// 字符串数组默认初始化值为空
	var arr3 = [3]string{"li", "li"}
	fmt.Println(arr3) // [li li ]

	/* 语法三  根据初始值的个数推断数组的长度*/
	var arr5 = [...]string{"1", "2", "3"}

	fmt.Println(arr5)

	/* 语法四 通过索引值初始化数组  通过索引:对应值初始化数组,长度为最大索引*/
	arr6 := [...]int{0: 1, 3: 4, 8: 9}
	fmt.Println(arr6) // [1 0 0 4 0 0 0 0 9]

}
数组循环遍历
go 复制代码
func main() {

	arr6 := [...]int{0: 1, 3: 4, 8: 9}
	fmt.Println(arr6) 
	// 通过遍历索引
	for i := 0; i < len(arr6); i++ {
		fmt.Println(arr6[i])
	}
	
	// 使用 range
	for _, v := range arr6 {
		fmt.Println(v)
	}
}
值类型和引用类型

基本数据类型和数组都属于值类型

go 复制代码
func main() {
	// 定义数组
	var arr = [3]int{1, 2, 3}
	// 值类型:赋值和传参赋值整个数组,改变变量副本的值的时候,不会改变本身的值
	arr2 := arr
	arr2[0] = 333
	fmt.Println(arr)  // [1 2 3]
	fmt.Println(arr2) // [333 2 3]

	// 定义切片
	var i = []int{1, 2, 3}
	// 引用类型:副本和原数据指向同一个内存地址,、改变变量副本的值的时候,会改变本身的值
	j := i
	j[0] = 333
	fmt.Println(i) //  [333 2 3]
	fmt.Println(j) //  [333 2 3]

} 
多维数组

多维数组可以理解为在数组中嵌套数组

go 复制代码
func main() {
	// 一维数组
	var arr1 = [3]int{1, 2, 3}
	fmt.Println(arr1)

	// 二维数组 指定长度
	var arr2 = [3][2]string{{"北京", "上海"}, {"1", "2"}, {"3", "4"}}
	fmt.Println(arr2) // [[北京 上海] [1 2] [3 4]]
  
  // 二维数组 让编译器通过数量推导长度, 只有第一层可以使用... 后面不可以
	var arr3 = [...][2]int{{1,2},{3,4}}
	fmt.Println(arr3)

	// 在二维基础上可以继续N维,取值就是通过下标取出一维再继续下标取值

	// 迭代二维数组
	for _, v1 := range arr2 {
		for _, v2 := range v1 {
			fmt.Println(v2)
		}

	}
}

切片

初始化数组
go 复制代码
	/* 语法一 */
	// 声明切片
	// 切片变量名 []切片类型,[]里面指定长度是数组,不指定是切片
	var arr []int
	fmt.Println(arr)        // []
	fmt.Println(arr == nil) //true go中声明的变量 但是变量没有赋值的时候,会给变量赋值一个默认零值,nil

	/* 语法二 */
	// 初始化切片时赋值
	var arr1 = []int{1, 2, 3, 4, 5, 6}
	fmt.Println(arr1) // [1 2 3 4 5 6]

	/* 语法三 通过索引赋值 长度是最大索引,没有指定值的索引默认值为0 */
	var arr2 = []int{1: 3, 7: 1}
	fmt.Println(arr2) // [0 3 0 0 0 0 0 1]
基于数组定义切片
go 复制代码
 // 获取数组里面的所有值
	var arr3 = [6]int{1, 2, 3, 4, 5, 6}
	var arr4 = arr3[:]
	fmt.Println(arr4) // [1 2 3 4 5 6]

	// 获取数组里面 从下标1开始 到下标4结束,包头不包尾
	var arr5 = arr3[1:4]
	fmt.Println(arr5) // [2 3 4]

	// 获取数组里面 从下标2开始到结束的所有值
	var arr6 = arr3[2:]
	fmt.Println(arr6) // [3 4 5 6]

	// 获取数组里面 从下标0开始开始到下标3前所有值
	var arr7 = arr3[:3]
	fmt.Println(arr7) // [1 2 3]
基于切片定义切片
go 复制代码
	// 下标1开始的所有数据,逻辑与基于数组定义切片一致
  var arr8 = []int{1, 2, 3}
	fmt.Println(arr8[1:]) // [2 3]
切片的长度和容量
go 复制代码
func main() {

	var arr = []int{1, 2, 3, 4, 5, 6, 7, 8}
	fmt.Println(len(arr), cap(arr))         // 长度8  容量8
	fmt.Println(len(arr[2:]), cap(arr[2:])) // 长度6 容量6

	/*
		长度是2  容量是7
		长度就是元素的个数 1:3 是2和3
		容量是从第一个元素开始,即从2开始,到底层数组(arr)元素末尾的个数,即从2到8,是对应的容量
	*/

	fmt.Println(len(arr[1:3]), cap(arr[1:3])) // 长度2 容量7

}
通过make方法构造切片
go 复制代码
func main() {
	// Param: 切片类型、切片长度、切片容量
	var arr = make([]int, 4, 8)
	fmt.Println(arr)      // [0 0 0 0] 默认值都是0
	fmt.Println(len(arr)) // 4
	fmt.Println(cap(arr)) // 8
	
	
	var arr1 []int
	fmt.Println(arr1)      // []
	fmt.Println(len(arr1)) // 0
	fmt.Println(cap(arr1)) // 0

}
append

切片扩容:

go 复制代码
func main() {

	// 不能使用下标给切片扩容,使用append动态扩容
	var arr1 []int
	fmt.Println(arr1)      // []
	fmt.Println(len(arr1)) // 0
	fmt.Println(cap(arr1)) // 0

	// Param:要扩容的切片,要添加的元素
	arr1 = append(arr1, 1)
	fmt.Println(arr1)      // [1]
	fmt.Println(len(arr1)) // 1
	fmt.Println(cap(arr1)) // 1

	// 批量扩容
	arr1 = append(arr1, 2, 3, 4, 5)
	fmt.Println(arr1)      // [1 2 3 4 5]
	fmt.Println(len(arr1)) // 5
	fmt.Println(cap(arr1)) // 6 

}

合并切片:

go 复制代码
func main() {

	arr1 := []int{1, 2, 3}
	arr2 := []int{4, 5, 6}
	// 将arr1切片的内容合并到arr2中,被合并的切片名后要加...
	arr2 = append(arr2, arr1...)
	fmt.Println(arr2) // [4 5 6 1 2 3]

}
copy

copy引用类型后修改副本变量,不影响原变量的值

go 复制代码
func main() {
	// 切片是引用数据类型
	arr1 := []int{1, 2, 3}
	arr2 := make([]int, 3, 4)
	// 使用copy 将arr1的值复制到arr2
	copy(arr2, arr1)
	fmt.Println(arr1) // [1 2 3]
	fmt.Println(arr2) // [1 2 3]

	// 修改arr2值,没有影响arr1,
	arr2[0] = 333
	fmt.Println(arr1) // [1 2 3]
	fmt.Println(arr2) // [333 2 3]
}
切片删除元素
go 复制代码
func main() {
	// golang中没有直接提供对应的方法删除元素,可以使用切片本身的特性删除元素

	// 使用append合并删除下标为2的元素
	arr1 := []int{1, 2, 3, 4, 5}
	arr1 = append(arr1[:2], arr1[3:]...)
	fmt.Println(arr1)

}
切片排序

选择排序和冒泡排序:

go 复制代码
func main() {
	/*
		通过比较 先选出最小的数放在第一个位置后,然后依次小的数往后放
	*/
	var numSlice = []int{10, 8, 6, 5, 4}
	for i := 0; i < len(numSlice); i++ {
		for j := i + 1; j < len(numSlice); j++ {

			if numSlice[i] > numSlice[j] {
				temp := numSlice[i]
				numSlice[i] = numSlice[j]
				numSlice[j] = temp
			}

		}

	}
	fmt.Println(numSlice) // [4 5 6 8 10]

	/*
	  冒泡排序:从头到尾,比较相邻的两个元素的大小,如果符合交互条件,交换两个元素的位置
	  每一轮比较都会选出一个最大的书放在正确的位置

	*/

	var numberSlice = []int{8, 3, 9, 4, 5}
	for i := 0; i < len(numberSlice); i++ {

		for j := 0; j < len(numberSlice)-1-i; j++ {
			if numberSlice[j] > numberSlice[j+1] {
				temp := numberSlice[j]
				numberSlice[j] = numberSlice[j+1]
				numberSlice[j+1] = temp

			}

		}

	}
	fmt.Println(numberSlice)

}

sort包:

sort升序排序:

go 复制代码
	var intList = []int{11, 21, 3, 45, 5, 6}
	var strList = []string{"z", "a", "d", "h", "g"}
	var floatList = []float64{3.14, 2.12, 5.3, 9.9, 8.8}
	// sort 升序排序
	sort.Ints(intList)
	sort.Strings(strList)
	sort.Float64s(floatList)

sort降序排序:

go 复制代码
	var intList = []int{11, 21, 3, 45, 5, 6}
	var strList = []string{"z", "a", "d", "h", "g"}
	var floatList = []float64{3.14, 2.12, 5.3, 9.9, 8.8}
	// sort 降序排序

	sort.Sort(sort.Reverse(sort.IntSlice(intList)))
	sort.Sort(sort.Reverse(sort.Float64Slice(floatList)))
	sort.Sort(sort.Reverse(sort.StringSlice(strList)))

map

map是无须的基于key-value的数据结构,map是引用类型,必须初始化才能使用

初始化map:
go 复制代码
	/* 语法一  通过make创建map */
	// Param: map[key的类型]value的类型,10是分配的初始容量,可传可不传
	// 指定初始容量的目的是为了在创建 map 时,预先分配一定的内存空间,以减少后续插入键值对时的内存重新分配次数。这可以提高性能,特别是在大规模的 map 中
	// 初始容量并不限制 map 存储的键值对数量,它只是一个指示性的值,map 会根据实际的键值对数量自动调整内部存储空间
	var user = make(map[string]string, 10)
	user["name"] = "lq"
	fmt.Println(user)

	/* 语法二 */
	var userInfo = map[string]string{
		"name": "l",
		"age":  "2",
		"sex":  "nan", // 最后复制的数据必须要加,
	}
	fmt.Println(userInfo)
查找某个key是否存在:
go 复制代码
	var userInfo = map[string]string{
		"name": "l",
		"age":  "2",
		"sex":  "nan", // 最后复制的数据必须要加,
	}
	fmt.Println(userInfo)
	// 查找某个key是否存在,两个变量接受,第一个是value,第二个是是否存在,存在是true,不存在是false
	// 如果查找的不存在,value则是对应数据的默认值,int是0,str是空
	value, status := userInfo["name"]
	fmt.Println(value, status) // l  true
删除键值对
go 复制代码
	var userInfo = map[string]string{
		"name": "l",
		"age":  "2",
		"sex":  "nan",
	}
	fmt.Println(userInfo) // map[age:2 name:l sex:nan]
	// delete方法删除map指定的key
	// Param: map,要删除的key
	delete(userInfo, "age")
	fmt.Println(userInfo) // map[name:l sex:nan]
元素为map类型的切片
go 复制代码
func main() {
	// 定义切片 类型是map
	var userinfo = make([]map[string]string, 1, 1)
	fmt.Println(userinfo) // [map[]]

	// map的默认值是nil
	if userinfo[0] == nil {
		// map必须初始化后才可以使用
		userinfo[0] = make(map[string]string)
		userinfo[0]["name"] = "1"
		userinfo[0]["age"] = "1"

	}
	fmt.Println(userinfo) // [map[age:1 name:1]]

}
值为切片类型的map
go 复制代码
	// 定义值为切片的map
	var userinfo = make(map[string][]string)
	// 赋值:初始化切片赋值
	userinfo["like"] = []string{"1", "2", "3"}
相关推荐
源代码•宸42 分钟前
Golang原理剖析(channel面试与分析)
开发语言·经验分享·后端·面试·golang·select·channel
moxiaoran57533 小时前
Go语言中的泛型
golang
加油20193 小时前
GO语言内存逃逸和GC机制
golang·内存管理·gc·内存逃逸
源代码•宸3 小时前
Golang原理剖析(channel源码分析)
开发语言·后端·golang·select·channel·hchan·sudog
liuyunshengsir3 小时前
golang Gin 框架下的大数据量 CSV 流式下载
开发语言·golang·gin
CHHC18803 小时前
golang 项目依赖备份
开发语言·后端·golang
老蒋每日coding3 小时前
AI智能体设计模式系列(八)—— 记忆管理模式
人工智能·设计模式·golang
且去填词20 小时前
深入理解 GMP 模型:Go 高并发的基石
开发语言·后端·学习·算法·面试·golang·go
a程序小傲20 小时前
京东Java面试被问:多活数据中心的流量调度和数据同步
java·开发语言·面试·职场和发展·golang·边缘计算
卜锦元1 天前
EchoChat搭建自己的音视频会议系统01-准备工作
c++·golang·uni-app·node.js·音视频