MST
星途 面试题库

面试题:Go语言中如何实现Map的深度拷贝

在Go语言中,直接赋值一个Map只会复制引用。请描述并实现一种方法来深度拷贝一个Map,即创建一个新的Map,其内部的所有键值对都是原Map的副本,包括嵌套的Map或切片。假设Map的键类型为string,值类型可能是int、string、嵌套的map[string]interface{} 或 []interface{} 等。
24.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "encoding/json"
    "fmt"
)

func deepCopy(m map[string]interface{}) map[string]interface{} {
    data, err := json.Marshal(m)
    if err != nil {
        panic(err)
    }

    var newMap map[string]interface{}
    err = json.Unmarshal(data, &newMap)
    if err != nil {
        panic(err)
    }

    return newMap
}

可以通过以下方式调用这个函数:

func main() {
    original := map[string]interface{}{
        "key1": 1,
        "key2": "value2",
        "key3": map[string]interface{}{
            "nestedKey": "nestedValue",
        },
        "key4": []interface{}{1, "two", map[string]interface{}{"subKey": "subValue"}},
    }

    copied := deepCopy(original)
    fmt.Printf("Original: %+v\n", original)
    fmt.Printf("Copied: %+v\n", copied)
}

通过 json.Marshaljson.Unmarshal 实现深度拷贝,将原 map 编码为JSON格式的字节切片,再将其解码为一个新的 map,这样就得到了一个完全独立的副本,包括嵌套的 mapslice

  1. deepCopy 函数
    • 首先使用 json.Marshal 将传入的 map 编码为JSON字节切片。如果编码过程中出现错误,使用 panic 抛出异常。
    • 然后声明一个新的 map[string]interface{} 类型变量 newMap,使用 json.Unmarshal 将编码后的字节切片解码到 newMap 中。如果解码过程出现错误,同样使用 panic 抛出异常。
    • 最后返回新创建的深度拷贝后的 map
  2. main 函数
    • 创建一个包含各种类型值(intstring、嵌套 map、嵌套 slice)的原始 map
    • 调用 deepCopy 函数对原始 map 进行深度拷贝,并将结果打印出来,展示原始 map 和拷贝后的 map 的内容。