From dbda09379d128f4077fa8fb76b50bf7c7005e19a Mon Sep 17 00:00:00 2001 From: huangzj Date: Fri, 15 May 2020 09:59:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(Go-StudyExample):=20=E6=B7=BB=E5=8A=A0Clon?= =?UTF-8?q?eExample,=E6=B5=8B=E8=AF=95go=E8=AF=AD=E8=A8=80=E7=9A=84?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=86=85=E5=AD=98=E5=92=8C=E6=B7=B1=E5=BA=A6?= =?UTF-8?q?=E5=85=8B=E9=9A=86=E7=9A=84=E5=AE=9E=E7=8E=B0=E5=85=B3=E4=BA=8E?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=85=8B=E9=9A=86=E5=8F=AF=E5=8F=82=E8=80=83?= =?UTF-8?q?=E6=96=87=E7=AB=A0[=E7=9F=A5=E4=B9=8E-](https://zhuanlan.zhihu.?= =?UTF-8?q?com/p/59125443)=E3=80=81[=E7=9F=A5=E4=B9=8E-](https://zhuanlan.?= =?UTF-8?q?zhihu.com/p/58065429)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Main.go | 3 + entity/DeepClone.go | 20 ++++++ example/CloneExample.go | 147 ++++++++++++++++++++++++++++++++++++++++ readme.md | 5 +- util/DeepCloneUtil.go | 39 +++++++++++ 5 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 entity/DeepClone.go create mode 100644 example/CloneExample.go create mode 100644 util/DeepCloneUtil.go diff --git a/Main.go b/Main.go index 8820962..de3dd5c 100644 --- a/Main.go +++ b/Main.go @@ -19,4 +19,7 @@ func main() { //--------------------------测试json包的转换功能 example.JsonMarshalTest() example.JsonUnmarshalTest() + + example.TestClone() + } diff --git a/entity/DeepClone.go b/entity/DeepClone.go new file mode 100644 index 0000000..bb59d01 --- /dev/null +++ b/entity/DeepClone.go @@ -0,0 +1,20 @@ +/* + * @Author : huangzj + * @Time : 2020/5/15 9:54 + * @Description: + */ + +package entity + +type SynthesisRuleCmp struct { + *SynthesisRule + RemainingSynthesisTime int + Sort int +} + +type SynthesisRule struct { + SynthesisId string `json:"SynthesisId"` + SynthesisNum int `json:"SynthesisNum"` + CostItems [][]int `json:"CostItems"` + SynthesisItems [][]int `json:"SynthesisItems"` +} diff --git a/example/CloneExample.go b/example/CloneExample.go new file mode 100644 index 0000000..655259e --- /dev/null +++ b/example/CloneExample.go @@ -0,0 +1,147 @@ +/* + * @Author : huangzj + * @Time : 2020/5/13 17:52 + * @Description:测试深拷贝和浅拷贝的代码类 + */ + +package example + +import ( + "Go-StudyExample/entity" + "Go-StudyExample/util" + "fmt" +) + +func TestClone() { + fmt.Print("\n\n\n") + fmt.Print(" Go语言深克隆的测试:\n\n") + + testJustBasicType() + + testHasPointType() + + fmt.Println("由此可见其实Go语言对于内存的分配,相对对象是独一份,对于对象的基本类型和值类型(结构体),应该是在其内部开辟了内存空间进行存储,而对于" + + "指针类型来说,直接使用它的地址(指针),不对结构体进行复制") + fmt.Println("") + + testDeepCloneByEncode() + + testDeepCloneByJsonPackage() + +} + +func testDeepCloneByJsonPackage() { + rule := entity.SynthesisRule{ + SynthesisId: "112", + SynthesisNum: 0, + CostItems: nil, + SynthesisItems: nil, + } + //这边必须是指定的类型,不然没办法转回去 + rule1, err := util.DeepCopyByJson(rule) + if err == nil && rule1 != &rule { + fmt.Println("") + fmt.Println("通过json包的方式可以实现深度克隆") + } +} + +func testDeepCloneByEncode() { + rule := entity.SynthesisRule{ + SynthesisId: "112", + SynthesisNum: 0, + CostItems: nil, + SynthesisItems: nil, + } + rule1 := new(entity.SynthesisRule) + err := util.DeepCopyByGob(rule1, rule) + if err != nil { + panic(err) + } + rule1.SynthesisId = "123" + if rule1 != &rule { + fmt.Println("通过序列化的方式可以实现深度克隆") + } +} + +func testJustBasicType() { + rule := entity.SynthesisRule{ + SynthesisId: "112", + SynthesisNum: 0, + CostItems: nil, + SynthesisItems: nil, + } + rule1 := rule + rule.SynthesisId = "222" + rule.SynthesisItems = make([][]int, 0) + rule.SynthesisItems = append(rule.SynthesisItems, []int{1}) + + if &rule1 != &rule { + fmt.Println("结构体中不存在指针,直接用 = 是") + fmt.Println("深克隆") + fmt.Println("") + } + +} + +func testHasPointType() { + cmp := entity.SynthesisRuleCmp{ + SynthesisRule: &entity.SynthesisRule{ + SynthesisId: "112", + SynthesisNum: 0, + CostItems: nil, + SynthesisItems: nil, + }, + RemainingSynthesisTime: 0, + Sort: 0, + } + + cmp1 := cmp + cmp.SynthesisId = "123" + if &cmp != &cmp1 && cmp.SynthesisRule == cmp1.SynthesisRule { + fmt.Println("结构体中存在指针,直接用 = 是深克隆") + fmt.Println("但是对于结构体中的指针来说是浅克隆,直接使用地址") + fmt.Println("") + } +} + +func testHasPointTypeList() { + + cmp := entity.SynthesisRuleCmp{ + SynthesisRule: &entity.SynthesisRule{ + SynthesisId: "112", + SynthesisNum: 0, + CostItems: nil, + SynthesisItems: nil, + }, + RemainingSynthesisTime: 0, + Sort: 0, + } + cmp1 := entity.SynthesisRuleCmp{ + SynthesisRule: &entity.SynthesisRule{ + SynthesisId: "112111", + SynthesisNum: 0, + CostItems: nil, + SynthesisItems: nil, + }, + RemainingSynthesisTime: 0, + Sort: 0, + } + list := make([]entity.SynthesisRuleCmp, 0) + list = append(list, cmp1) + list = append(list, cmp) + + list1 := make([]entity.SynthesisRuleCmp, len(list)) + cmp.RemainingSynthesisTime = 1000 + fmt.Println(cmp1.RemainingSynthesisTime) + copy(list1, list) + list1[0].SynthesisId = "12333" + if list[0].SynthesisId == list1[0].SynthesisId { + fmt.Println("非深度克隆") + } + + list2 := list[0:] + list2[0].SynthesisId = "54323" + if list[0].SynthesisId == list2[0].SynthesisId { + fmt.Println("非深度克隆") + } +} diff --git a/readme.md b/readme.md index ff969fd..82d9aec 100644 --- a/readme.md +++ b/readme.md @@ -2,4 +2,7 @@ 2020/4/27 :创建项目,添加使用示例如下: map与struct之间转换的处理工具使用示例,参考代码地址:https://github.com/mitchellh/mapstructure -json与struct之间转换处理工具使用示例 \ No newline at end of file +json与struct之间转换处理工具使用示例 + + +2020/5/15 : 添加CloneExample,测试go语言的对象内存和深度克隆的实现关于对象克隆可参考文章[知乎-](https://zhuanlan.zhihu.com/p/59125443)、[知乎-](https://zhuanlan.zhihu.com/p/58065429) \ No newline at end of file diff --git a/util/DeepCloneUtil.go b/util/DeepCloneUtil.go new file mode 100644 index 0000000..75dc87a --- /dev/null +++ b/util/DeepCloneUtil.go @@ -0,0 +1,39 @@ +/* + * @Author : huangzj + * @Time : 2020/5/14 17:53 + * @Description: + */ + +package util + +import ( + "Go-StudyExample/entity" + "bytes" + "encoding/gob" + "encoding/json" +) + +/* + * @param dst 目标对象 + * @param src 源对象 + * 通过序列化的方式进行克隆 + */ +func DeepCopyByGob(dst, src interface{}) error { + var buffer bytes.Buffer + if err := gob.NewEncoder(&buffer).Encode(src); err != nil { + return err + } + + return gob.NewDecoder(&buffer).Decode(dst) +} + +func DeepCopyByJson(src interface{}) (*entity.SynthesisRule, error) { + var dst = new(entity.SynthesisRule) + b, err := json.Marshal(src) + if err != nil { + return nil, err + } + + err = json.Unmarshal(b, dst) + return dst, err +}