2. Copy the structure by reflection
Package Mainimport ("FMT" "Reflect" "Time") type (Player struct {Id intlevel intheroes map[int]*heroequips []*equip}hero struct {ID intlevel intskills []*skill}equip struct {id intlevel int}skill struct {id intlevel int}] Func newhe Ro () *hero {return &hero{id:1,level:1,skills:append ([]*skill{newskill ()}, Newskill (), Newskill ()),}}func NewSk Ill () *skill {return &skill{1, 1}}func newequip () *equip {return &equip{1, 1}}func newplayer () *player {return &am P Player{id:1,level:1,heroes:map[int]*hero{1:newhero (), 2:newhero (), 3:newhero ()},equips:append ([]*Equip{NewEq uIP ()}, Newequip (), Newequip ()),}}func (self *hero) Print () {fmt. Printf ("id=%d, level=%d\n", self.) Id, self. Level) For _, V: = Range self. Skills {fmt. Printf ("%v\n", *v)}}func (self *player) Print () {fmt. Printf ("id=%d, level=%d\n", self.) Id, self. Level) For _, V: = Range self. Heroes {V.print ()}for _, V: = Range self. equips {FMT. Printf ("%+v\n", *v)}}type Interface Interface {deepcopy () InterFace{}}func Copy (src interface{}) interface{} {if src = = nil {return nil}original: = reflect. ValueOf (src) cpy: = reflect. New (original. Type ()). Elem () copyrecursive (original, cpy) return cpy. Interface ()}func copyrecursive (SRC, DST reflect. Value) {if src. Caninterface () {if copier, ok: = src. Interface (). (Interface); OK {DST. Set (reflect. ValueOf (copier. Deepcopy ())) Return}}switch src. Kind () {case reflect. Ptr:originalvalue: = src. Elem () if!originalvalue.isvalid () {return}dst. Set (reflect. New (Originalvalue.type ())) copyrecursive (OriginalValue, DST. Elem ()) case reflect. Interface:if src. Isnil () {return}originalvalue: = src. Elem () Copyvalue: = reflect. New (Originalvalue.type ()). Elem () copyrecursive (OriginalValue, Copyvalue) DST. Set (Copyvalue) case reflect. Struct:t, OK: = src. Interface (). (Time. Time) If OK {DST. Set (reflect. ValueOf (t)) return}for I: = 0; I < SRC. Numfield (); i++ {if src. Type (). Field (i). Pkgpath! = "" {continue}copyrecursive (src. Field (i), DST. Field (i))}case reflect. Slice:if src. Isnil () {Return}dsT.set (reflect. Makeslice (src. Type (), Src. Len (), Src. Cap ())) for I: = 0; I < SRC. Len (); i++ {copyrecursive (src. Index (i), DST. Index (i))}case reflect. Map:if src. Isnil () {return}dst. Set (reflect. Makemap (src. Type ()))) for _, Key: = Range src. Mapkeys () {originalvalue: = src. Mapindex (key) Copyvalue: = reflect. New (Originalvalue.type ()). Elem () copyrecursive (OriginalValue, copyvalue) Copykey: = Copy (key. Interface ()) DST. Setmapindex (reflect. ValueOf (Copykey), Copyvalue)}default:dst. Set (SRC)}}func main () {p1: = Newplayer () P2: = Copy (p1). *player) fmt. Println (reflect. Deepequal (P1, p2))}//output true//Benchamark test func benchmarkreflect (b *testing. B) {p1: = Newplayer () for i:=0; i<b.n; i++ {Copy (p1)}}goos:windowsgoarch:amd64pkg:game.lab/go-deepcopy/src/reflect2 00000 10725 Ns/oppass