DeepCloning a datastructure

449 views
Skip to first unread message

Marc Schöchlin

unread,
Apr 16, 2020, 5:07:43 PM4/16/20
to golan...@googlegroups.com
Hello List,

i am searching for a convenient way to deep-clone a nested datastructure.

My data structure looks like this:

(map[string]map[string]*processing.AccountingSet) (len=1) {
 (string) (len=16) "foo1.bar.com:443": (map[string]*processing.AccountingSet) (len=1) {
  (string) (len=3) "all": (*processing.AccountingSet)(0xc000090060)({
   count: (int64) 90,
   sum: (int64) 80000001480,
   codes: (map[int]int) (len=1) {
    (int) 301: (int) 90
   },
   classes: (map[int]int) (len=6) {
    (int) 0: (int) 90,
    (int) 500000: (int) 0,
    (int) 5000000: (int) 0,
    (int) 10000000: (int) 0,
    (int) 60000000: (int) 0,
    (int) 300000000: (int) 0
   }
  })
 }
}

How can i make a exact, deep, and completely independent copy of that structure?

What i tried:
(c.stats contains the mentioned data structure which should by copied to c.stats)

import "github.com/ulule/deepcopier"

c.lastStats = map[string]map[string]*AccountingSet{}
err = deepcopier.Copy(c.stats).To(c.lastStats)
if err != nil {
        glog.Errorf("unable to clone : '%s'", err.Error())
}

This doesn't work. The target structure is empty after the copy operation.

Regards
Marc


Hugh Emberson

unread,
Apr 17, 2020, 12:03:12 AM4/17/20
to Marc Schöchlin, golang-nuts
On Thu, Apr 16, 2020 at 2:07 PM Marc Schöchlin <m...@256bit.org> wrote:
i am searching for a convenient way to deep-clone a nested datastructure.

I've used https://github.com/mohae/deepcopy with some success.  YMMV.

Regards,
Hugh

Hugh Emberson

unread,
Apr 17, 2020, 12:46:42 AM4/17/20
to Marc Schöchlin, golang-nuts
And, I realized just after posting that your data structure has private fields in it as https://github.com/mohae/deepcopy won't work on those.


Carsten Orthbandt

unread,
Apr 17, 2020, 4:37:40 AM4/17/20
to golang-nuts
The easiest way is to marshal everything into some sort of byte slice, then unmarshal back. JSON doesn't work for this if there are private fields. But gotiny (https://github.com/niubaoshu/gotiny) does. If you use interfaces in your data, you have to register their types, everthing else is automatic.

Ankit R Gadiya

unread,
Apr 18, 2020, 1:26:11 PM4/18/20
to Carsten Orthbandt, golang-nuts
How about doing it manually? You can define a DeepCopy method on the type and manually allocate a new struct and initialize the maps and slices by looping over them. That way you get to have more control over all the fields and problem of private fields is solved as well. I would guess this would be faster as well because no reflection is required.

As far as I know Kubernetes uses this approach and they have a code-generator which can conveniently generate the code for the structs.




On Fri, Apr 17, 2020 at 2:07 PM Carsten Orthbandt <carsten....@gmail.com> wrote:
The easiest way is to marshal everything into some sort of byte slice, then unmarshal back. JSON doesn't work for this if there are private fields. But gotiny (https://github.com/niubaoshu/gotiny) does. If you use interfaces in your data, you have to register their types, everthing else is automatic.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/17810cd4-dab5-4583-8944-aed38b773232%40googlegroups.com.

Zhaoxun Yan

unread,
May 6, 2022, 5:54:07 AM5/6/22
to golang-nuts
Yes there are two open source packages regarding "DeepCopy"


Has anyone tried them yet?
Reply all
Reply to author
Forward
0 new messages