notes 笔记notes 笔记
Home
Article
Category
Tag
Timeline
Home
Article
Category
Tag
Timeline
  • build

    • 环境变量
  • browse

    • 2fa
    • sse
    • token
  • database

    • mongodb

      • start
    • mysql

      • curd
      • 安装
      • join
      • 多对多
      • 性能优化
      • 表设计
      • 常见问题
  • docker

    • github-actions

      • local
      • prod
    • docker-compose
    • index
    • podman
  • file

    • 文件下载
    • 原生 node.js下载文件
  • git

    • index
    • multiple-github-accounts
    • auto-commit
    • pat
    • rebase
  • linux

    • grep
    • index
    • ssh
    • vim
    • windows
  • network

    • best-proxy-way
    • git-via-https
    • github-push-fail
  • nginx

    • acme.sh
    • cache
    • https
    • index
    • safe
  • node

    • fnm
    • tool
  • obsidian

    • ish
    • start
  • react

    • index
    • set-state
  • summary

    • index
  • vue

    • index
    • typescript
  • libs
  • open-source

map 类型如何复制

在 Go 语言中,map 是引用类型(类似切片、通道),直接赋值只会复制引用(即两个变量指向同一个底层数据结构),修改其中一个会影响另一个。因此,若需要真正复制一个 map(即创建独立的副本,修改副本不影响原 map),需要手动遍历原 map 并将键值对逐一复制到新 map 中。

1. 错误的复制方式(仅复制引用)

直接赋值会导致两个 map 共享底层数据,修改任一都会相互影响:

package main

import "fmt"

func main() {
    original := map[string]int{"a": 1, "b": 2}
    copyMap := original // 仅复制引用,不是真正的复制

    copyMap["a"] = 100  // 修改副本
    fmt.Println(original["a"]) // 输出 100(原 map 也被修改了)
}

2. 正确的复制方式(深度复制)

需要手动创建新 map,然后遍历原 map 的键值对,逐一存入新 map:

package main

import "fmt"

func copyMap(original map[string]int) map[string]int {
    // 创建新 map,容量可指定为原 map 大小(可选,提升性能)
    newMap := make(map[string]int, len(original))
    // 遍历原 map,复制键值对到新 map
    for k, v := range original {
        newMap[k] = v
    }
    return newMap
}

func main() {
    original := map[string]int{"a": 1, "b": 2}
    copyMap := copyMap(original) // 真正的复制

    copyMap["a"] = 100          // 修改副本
    fmt.Println(original["a"])  // 输出 1(原 map 不受影响)
    fmt.Println(copyMap["a"])   // 输出 100
}

3. 特殊情况:嵌套 map 的复制

如果 map 的值是嵌套 map(即 map[K]map[K]V),上述方法只能复制外层 map,内层 map 仍然是引用类型。此时需要递归复制内层 map 才能完全独立:

package main

import "fmt"

// 递归复制嵌套 map
func deepCopy(original map[string]map[int]string) map[string]map[int]string {
    newMap := make(map[string]map[int]string, len(original))
    for k, v := range original {
        // 对内层 map 也进行复制
        innerMap := make(map[int]string, len(v))
        for k2, v2 := range v {
            innerMap[k2] = v2
        }
        newMap[k] = innerMap
    }
    return newMap
}

func main() {
    original := map[string]map[int]string{
        "group1": {1: "a", 2: "b"},
    }
    copyMap := deepCopy(original)

    // 修改副本的内层 map
    copyMap["group1"][1] = "x"
    fmt.Println(original["group1"][1]) // 输出 a(原 map 不受影响)
}

总结:

  • map 是引用类型,直接赋值不会复制数据,只会共享底层结构。
  • 浅复制(单一层次 map):创建新 map 并遍历复制键值对。
  • 深复制(嵌套 map):需要递归复制所有层级的 map,确保所有数据独立。
  • 复制时指定新 map 的初始容量(make(map[K]V, len(original)))可减少动态扩容,提升性能。
最近更新:: 2025/12/30 00:02
Contributors: qyhever