Golang第四章:数组和切片
数组
数组初始化
数组遍历——for-range结构遍历
// 演示for-range遍历数组 heroes := [...]string{"宋江", "李逵","晁盖"} for index, value := range heroes { fmt.Printf("i=%v, v=%v\n", index, value) }
二维数组遍历
var arr3 = [2][3]int{{1, 2, 3}, {4, 5, 6}} for i := 0; i < len(arr3); i++ { for j := 0; j < len(arr3[i]); j++ { fmt.Printf("%v\t", arr3[i][j]) } }
数组使用细节
1. 数组是多个相同类型数据的组合,一个数组一旦声明/定义了,其长度是固定的,不能动态变化
2. 数组创建后,如果没有赋值,则有默认值。字符串:“”; 数值:0; bool数组:false
3. 数组默认情况下是值传递,若想修改原数组,可以使用引用传递
4. 长度是数组类型的一部分,传递函数参数时,需要考虑数组的长度,如下方的 arr * [3]
func main() { heroes := [...]string{"宋江", "李逵","晁盖"} test02(&heroes) } func test02(arr *[3] string) { (*arr)[0] = "老头" }
切片
基本介绍
1. 切片是数组的一个引用,在进行传递时,遵守引用传递机制;
2. 切片的长度是可以变化的,因此切片是一个动态变化数组
3. 切片定义:var 变量名 [] 类型,如 var a [] int
4. 从底层看,其实是一个struct结构体,里面存有指针、len和cap
5. var slice = arr[0:len(arr)]可以简写为var slice = arr[:]
6. 切片可以继续切片
func main() { var intArr [5] int = [...] int{1, 22, 3, 5, 6} // 切片使用方式1 // slice := intArr[1:3] // 切片使用方式2 // var slice [] int = make([]int, 5, 10) // 第三个cap参数可选 // slice[0] = 1 // slice[1] = 22 // slice[2] = 3 // slice[3] = 5 // slice[4] = 6 // 切片使用方式3 var slice [] int = [] int {1, 22, 3, 5, 6} fmt.Println("intArr=", intArr) fmt.Println("slice=", slice) // 22, 3 fmt.Println("slice元素个数=", len(slice)) // 2 fmt.Println("slice容量=", cap(slice)) // 切片的容量可以动态变化 }
append操作底层原理分析
1. 切片append操作的本质是对数组扩容
2. go底层会创建一个新的数组newArr
3. 将slice原来的元素拷贝到新数组newArr中
4. slice重新引用到newArr
// 切片使用方式3 var slice [] int = [] int {1, 22, 3, 5, 6} // 通过append直接给slice追加具体元素 slice = append(slice, 300, 400) // 1 22 3 5 6 300 400 // 通过append将切片slice追加给切片slice slice = append(slice, slice...) // 1 22 3 5 6 300 400 1 22 3 5 6 300 400
切片的copy操作
var slice [] int = [] int {1, 22, 3, 5, 6} var a[] int = []int {2} copy(slice, a) // 2 22 3 5 6 300 400
map
声明是不会分配内存的,初始化需要make,分配内存后才能赋值和使用;key-value无序
func main() { var a map[string]string // 使用map前,需要先make,make的作用就是给map分配数据空间 a = make(map[string]string, 10) a["no1"] = "老头" a["no2"] = "小孩" a["no3"] = "女人" fmt.Println(a) }
map查删操作
cities := make(map[string]string) cities["no1"] = "北京" cities["no2"] = "上海" cities["no3"] = "深圳" fmt.Println(cities) // map的查找 val, findRes := cities["no1"] if findRes { fmt.Println(val) }else { fmt.Println("没找到") } // 删除一个 delete(cities, "no1") fmt.Println(cities) // no2:上海;no3:深圳 // 删除所有 cities = make(map[string]string) fmt.Println(cities) // map[]
map遍历
cities := make(map[string]string) cities["no1"] = "北京" cities["no2"] = "上海" cities["no3"] = "深圳" fmt.Println(cities) for i, v := range(cities) { fmt.Printf("i=%v, v=%v;", i, v) }
map切片
//1. 声明一个map切片 var monsters []map[string]string = make([]map[string]string, 2) // 2.增加一个妖怪的信息 if monsters[0] == nil { monsters[0] = make(map[string]string, 2) monsters[0]["name"] = "牛魔王" monsters[0]["age"] = "500" } if monsters[1] == nil { monsters[1] = make(map[string]string, 2) monsters[1]["name"] = "玉兔精" monsters[1]["age"] = "400" } fmt.Println(monsters)// [map[age:500 name:牛魔王] map[age:400 name:玉兔精] // 3.map切片扩容 newMonster := map[string]string{ "name": "老头怪", "age": "200", } monsters = append(monsters, newMonster) fmt.Println(monsters) // [map[age:500 name:牛魔王] map[age:400 name:玉兔精] map[age:200 name:老头怪]]
map无序转有序
peoples := map[int]string { 1: "好孩子", 6: "老人家", 5: "好大夫", } var keys []int for i, _ := range(peoples) { keys = append(keys, i) } sort.Ints(keys) for _, k := range(keys) { fmt.Printf("%v:%v;", k, peoples[k]) //1:好孩子;5:好大夫;6:老人家 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?