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:老人家
    }
复制代码

 

posted @   天叔  阅读(170)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示