go深度拷貝reflect版

來源:互聯網
上載者:User

2.通過反射的方式拷貝結構

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 NewHero() *Hero {return &Hero{Id:     1,Level:  1,Skills: append([]*Skill{NewSkill()}, NewSkill(), NewSkill()),}}func NewSkill() *Skill {return &Skill{1, 1}}func NewEquip() *Equip {return &Equip{1, 1}}func NewPlayer() *Player {return &Player{Id:     1,Level:  1,Heroes:   map[int]*Hero{1: NewHero(), 2: NewHero(), 3: NewHero()},Equips: append([]*Equip{NewEquip()}, 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))}// 輸出true// benchamark測試func BenchmarkReflect(b *testing.B) {p1 := NewPlayer()for i:=0 ; i<b.N ; i++ {Copy(p1)}}goos: windowsgoarch: amd64pkg: game.lab/go-deepcopy/src/reflect200000     10725 ns/opPASS

  

  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.