Использование простого цикла for range
является наиболее эффективным решением.
Обратите внимание, что встроенный copy
не может просто скопировать память src
по адресу dst
, поскольку они могут иметь совершенно разную структуру памяти. Карты растут в соответствии с количеством элементов, хранящихся в них. Так, например, если у вас есть карта с миллионом элементов, она занимает гораздо больше памяти, чем недавно созданная новая карта, и поэтому встроенная copy
не может просто скопировать память без выделения новой.
Если ваша карта большая, вы можете ускорить копирование элементов, если сможете создать карту назначения с достаточно большой емкостью, чтобы избежать перефразирования и перераспределения (начальная емкость не ограничивает ее размер), например:
dst := make(map[K]V, len(src))
for k, v := range src {
dst[k] = v
}
Если производительность не является проблемой (например, вы работаете с небольшими картами), общее решение может быть создано с использованием пакета reflect
:
func MapCopy(dst, src interface{}) {
dv, sv := reflect.ValueOf(dst), reflect.ValueOf(src)
for _, k := range sv.MapKeys() {
dv.SetMapIndex(k, sv.MapIndex(k))
}
}
Это решение не проверяет, являются ли аргументы действительно картами и не является ли пункт назначения nil
. Тестируем это:
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)
Вывод (попробуйте на Go Playground ):
map[1:one 2:two]
map[one:1 two:2]