notexOPENOverview
Notex/Languages/Copying Maps
01.26LESSON 26 OF 33 · 2 MIN READ

Copying Maps

Always free to read

Assigning a map variable to another map variable shares the map between the two variables. If you modify one variable, the other is modified as well. This is similar to the way slices behave, which was discussed in “Sharing and Copying Slices”. Here is an example on The Go Playground:

x := map[string]int{
    "magic": 3,
    "hero":  0,
    "good":  11,
}
y := x
y["naughty"] = 9
fmt.Println(x) // prints map[good:11 hero:0 magic:3 naughty:9]

Like slices, Go provides two ways to duplicate a map. While the built-in function copy does not work for maps, the maps package provides a pair of methods for copying maps: Copy, which is similar to the built-in copy function for slices, and Clone, which is similar to slices.Clone. For maps.Copy, you pass in a destination map and a source map. All the key/value pairs in the source are copied to the destination. The destination map does not need to be empty; if it contains a key that is also in the source map, the value in the destination map is overwritten. You can see this behavior on The Go Playground:

from := map[string]int{
    "hello": 5,
    "world": 10,
}
to := map[string]int{
    "hello":   30,
    "goodbye": 11,
}
maps.Copy(to, from)
fmt.Println(to) // prints map[goodbye:11 hello:5 world:10]

The maps.Clone function returns a new map with a copy of all the key/value pairs in the source map. You can see this on The Go Playground:

x := map[string]int{
    "uno":  1,
    "dos":  2,
    "tres": 3,
}
y := maps.Clone(x)
y["catorce"] = 14
y["uno"] = 0
fmt.Println(x) // prints map[dos:2 tres:3 uno:1]
fmt.Println(y) // prints map[catorce:14 dos:2 tres:3 uno:0]

Notice that modifying the clone doesn’t modify the original. However, you should be aware of an interaction between pointers and the copy functions for maps and slices. These functions make shallow copies. When copying a value that contains a pointer, the data pointed to by the pointer isn’t duplicated; the pointer is. If the value pointed to by the pointer is modified, the modification appears in both the original and the copy. This is similar to the behavior you saw when assigning a map or slice to a new variable. You can see it demonstrated on The Go Playground:

original := map[string][]int{
    "fives":  []int{0, 5, 10},
    "threes": []int{0, 3, 6, 9},
}
clone := maps.Clone(original)
clone["fives"][0] = -5
clone["sixes"] = []int{0, 6, 12}
fmt.Println(original["fives"], clone["fives"]) // prints [-5 5 10] [-5 5 10]
fmt.Println(original["sixes"], clone["sixes"]) // prints [], [0 6 12]

Both slices and maps contain pointers, which is why we see this behavior. Notice that adding a new entry to the clone doesn’t modify the original. It’s when you modify one of the slices that is already there that the change is shared. Again, I’ll cover pointers in detail in the related discussion.

Progress is saved on this device.
KEEP EXPLORING

One note leads to another.

Back to the library →
⌕
Search across the entire library ⌘ K