go语言中map学习

在 Go 语言中,map 是一种引用类型,这意味着它有以下特点:

  1. 内存结构map 实际上是一个指向底层数据结构的指针。这个底层数据结构包含键值对的集合。

  2. 赋值与传参: 当你给一个变量赋值一个 map 时,或者将 map 作为函数参数传递时,实际上传递的是指针,而不是完整的数据结构副本。这意味着, 通过这种方式修改 map 的内容,其他引用同一个 map 的变量也能看到这些修改。

  3. 零值: 一个未初始化的 map 变量的零值是 nilnil map 不能用于存储键值对,需要使用 make() 函数来创建一个可用的 map

  4. 并发安全性: 由于 map 是引用类型,在并发访问时需要特别注意线程安全问题。多个goroutine同时读写同一个 map 可能会导致数据竞争,需要使用互斥锁或者其他并发控制手段来保证线程安全

给出几个例子来说明 map 作为引用类型在赋值和传参时的行为:

  1. 赋值:
package main

import "fmt"

func main() {
    // 创建一个 map
    m1 := map[string]int{
        "apple": 5,
        "banana": 3,
    }

    // 赋值给 m2
    m2 := m1

    // 修改 m2 中的值
    m2["apple"] = 10

    // 打印 m1 和 m2
    fmt.Println("m1:", m1)
    fmt.Println("m2:", m2)
}

输出:

m1: map[apple:10 banana:3]
m2: map[apple:10 banana:3]

可以看到,当我们将 m1 赋值给 m2 时,m2 实际上是指向了与 m1 相同的底层 map 数据结构。所以当我们修改 m2 中的值时, m1 中的值也发生了变化。

  1. 函数传参:
package main

import "fmt"

func modifyMap(m map[string]int) {
    m["apple"] = 10
}

func main() {
    // 创建一个 map
    m := map[string]int{
        "apple": 5,
        "banana": 3,
    }

    // 调用函数并打印 m
    modifyMap(m)
    fmt.Println("m:", m)
}
m: map[apple:10 banana:3]

在这个例子中,我们将 m 作为参数传递给 modifyMap 函数。由于 map 是引用类型,在函数内部对 m 的修改会反映到调用方的 m 上。

如果你不想在函数中改变原来的 m 变量,有以下两种方式可以处理:

  1. 复制一个新的 map:
    package main
    
    import "fmt"
    
    func modifyMap(m map[string]int) {
        // 创建一个新的 map 并修改
        newM := make(map[string]int, len(m))
        for k, v := range m {
            newM[k] = v
        }
        newM["apple"] = 10
    }
    
    func main() {
        // 创建一个 map
        m := map[string]int{
            "apple": 5,
            "banana": 3,
        }
    
        // 调用函数并打印 m
        modifyMap(m)
        fmt.Println("m:", m)
    }
  2. 使用指针传参:
    package main
    
    import "fmt"
    
    func modifyMap(m *map[string]int) {
        // 修改传入的 map 指针
        (*m)["apple"] = 10
    }
    
    func main() {
        // 创建一个 map
        m := map[string]int{
            "apple": 5,
            "banana": 3,
        }
    
        // 调用函数并打印 m
        modifyMap(&m)
        fmt.Println("m:", m)
    }
    m: map[apple:10 banana:3]

    在这个例子中,我们将 m 的地址传递给 modifyMap 函数,并在函数内部通过解引用的方式修改 m 的值。这种方式也可以避免修改原 m 变量。

    总之,关键是要理解 map 是引用类型,如果不想在函数中修改原 map 变量,可以选择复制一个新的 map 或者使用指针传参的方式。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值