Given
var dst, src map[K]V
I can copy all entries from src
into dst
by doing
for k, v := range src { dst[k] = v }
Is there a more idiomatic way to do this?
copy
only works on slices (and string
as a source).
Maps in Go are reference types, so to deep copy the contents of a map, you cannot assign one instance to another. You can do this by creating a new, empty map and then iterating over the old map in a for range loop to assign the appropriate key-value pairs to the new map.
That looks like a perfectly fine way to do this to me. I don't think copying one map into another is common enough to have a one-liner solution.
Using a simple for range
loop is the most efficient solution.
Note that a builtin copy
could not just copy the memory of src
to the address of dst
because they may have entirely different memory layout. Maps grow to accommodate the number of items stored in them. So for example if you have a map with a million elements, it occupies a lot more memory than a freshly created new map, and so a builtin copy
could not just copy memory without allocating new.
If your map is big, you can speed up copying elements if you may create the destination map having a big-enough capacity to avoid rehashing and reallocation (the initial capacity does not bound its size), e.g.:
dst := make(map[K]V, len(src)) for k, v := range src { dst[k] = v }
If performance is not an issue (e.g. you're working with small maps), a general solution may be created using the reflect
package:
func MapCopy(dst, src interface{}) { dv, sv := reflect.ValueOf(dst), reflect.ValueOf(src) for _, k := range sv.MapKeys() { dv.SetMapIndex(k, sv.MapIndex(k)) } }
This solution does not check if the arguments are really maps and if the destination is not nil
. Testing it:
m1 := map[int]string{1: "one", 2: "two"} m2 := map[int]string{} MapCopy(m2, m1) fmt.Println(m2) m3 := map[string]int{"one": 1, "two": 2} m4 := map[string]int{} MapCopy(m4, m3) fmt.Println(m4)
Output (try it on the Go Playground):
map[1:one 2:two] map[one:1 two:2]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With