Wie in seongs Kommentar angegeben :
Siehe auch http://golang.org/doc/effective_go.html#maps . Der wichtige Teil ist wirklich der "Verweis auf die zugrunde liegende Datenstruktur". Dies gilt auch für Scheiben.
Keine der hier aufgeführten Lösungen scheint jedoch eine Lösung für eine ordnungsgemäße Tiefenkopie zu bieten, die auch Slices abdeckt.
Ich habe die Antwort von Francesco Casula leicht geändert , um sowohl Karten als auch Slices zu berücksichtigen.
Dies sollte sowohl das Kopieren Ihrer Karte selbst als auch das Kopieren von untergeordneten Karten oder Slices umfassen. Beide sind von demselben Problem der "zugrunde liegenden Datenstruktur" betroffen. Es enthält auch eine Dienstprogrammfunktion zum direkten Ausführen derselben Art von Deep Copy für ein Slice.
Beachten Sie, dass die Scheiben in der resultierenden Karte vom Typ sein []interface{}
, so dass , wenn sie verwenden, müssen Sie verwenden Typ Behauptung den Wert in der erwarteten Art abzurufen.
Beispiel Verwendung
copy := CopyableMap(originalMap).DeepCopy()
Quelldatei ( util.go
)
package utils
type CopyableMap map[string]interface{}
type CopyableSlice []interface{}
func (m CopyableMap) DeepCopy() map[string]interface{} {
result := map[string]interface{}{}
for k,v := range m {
mapvalue,isMap := v.(map[string]interface{})
if isMap {
result[k] = CopyableMap(mapvalue).DeepCopy()
continue
}
slicevalue,isSlice := v.([]interface{})
if isSlice {
result[k] = CopyableSlice(slicevalue).DeepCopy()
continue
}
result[k] = v
}
return result
}
func (s CopyableSlice) DeepCopy() []interface{} {
result := []interface{}{}
for _,v := range s {
mapvalue,isMap := v.(map[string]interface{})
if isMap {
result = append(result, CopyableMap(mapvalue).DeepCopy())
continue
}
slicevalue,isSlice := v.([]interface{})
if isSlice {
result = append(result, CopyableSlice(slicevalue).DeepCopy())
continue
}
result = append(result, v)
}
return result
}
Testdatei ( util_tests.go
)
package utils
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestCopyMap(t *testing.T) {
m1 := map[string]interface{}{
"a": "bbb",
"b": map[string]interface{}{
"c": 123,
},
"c": []interface{} {
"d", "e", map[string]interface{} {
"f": "g",
},
},
}
m2 := CopyableMap(m1).DeepCopy()
m1["a"] = "zzz"
delete(m1, "b")
m1["c"].([]interface{})[1] = "x"
m1["c"].([]interface{})[2].(map[string]interface{})["f"] = "h"
require.Equal(t, map[string]interface{}{
"a": "zzz",
"c": []interface{} {
"d", "x", map[string]interface{} {
"f": "h",
},
},
}, m1)
require.Equal(t, map[string]interface{}{
"a": "bbb",
"b": map[string]interface{}{
"c": 123,
},
"c": []interface{} {
"d", "e", map[string]interface{} {
"f": "g",
},
},
}, m2)
}