博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
go深度拷贝reflect版
阅读量:5234 次
发布时间:2019-06-14

本文共 2914 字,大约阅读时间需要 9 分钟。

2.通过反射的方式拷贝结构

package mainimport ("fmt""reflect""time")type (	Player struct {		Id     int		Level  int		Heroes map[int]*Hero		Equips []*Equip	}	Hero struct {		Id     int		Level  int		Skills []*Skill	}	Equip struct {		Id    int		Level int	}	Skill struct {		Id    int		Level 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

  

  

转载于:https://www.cnblogs.com/LittleLee/p/9334129.html

你可能感兴趣的文章
【android】安卓的权限提示及版本相关
查看>>
JavaScript可否多线程? 深入理解JavaScript定时机制
查看>>
IOS基础学习
查看>>
PHP 导出 Excell
查看>>
Java基础教程——网络基础知识
查看>>
自己到底要的是什么
查看>>
Kruskal基础最小生成树
查看>>
ubuntu 14.04 安装搜狗拼音输入法
查看>>
浅谈算法和数据结构: 一 栈和队列
查看>>
Java内部类详解
查看>>
【hdu 1429】胜利大逃亡(续)
查看>>
图论-次短路求法
查看>>
What's New for Visual C# 6.0
查看>>
ExtJs学习笔记之ComboBox组件
查看>>
关于收费软件
查看>>
getopt_long
查看>>
TensorFlow MNIST CNN 代码
查看>>
javascript之Style物
查看>>
JSON跨域解决方案收集
查看>>
SSH框架整合总结
查看>>