-
Notifications
You must be signed in to change notification settings - Fork 0
/
gob_deepcopy.go
115 lines (94 loc) · 2.84 KB
/
gob_deepcopy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package deepcopy
import (
"bytes"
"encoding/gob"
"fmt"
"github.com/devlights/gomy/output"
)
// GobDeepCopy -- encoding/gob を利用した deep-copy のサンプルです.
//
// REFERENCES:
// - https://stackoverflow.com/questions/46790190/quicker-way-to-deepcopy-objects-in-golang
// - https://stackoverflow.com/questions/37618399/efficient-go-serialization-of-struct-to-disk/37620399#37620399
// - https://www.reddit.com/r/golang/comments/2vzmp7/deepcopy_of_a_slice_of_structs/
// - https://groups.google.com/forum/#!topic/golang-nuts/vK6P0dmQI84
func GobDeepCopy() error {
// --------------------------------------------------------------------------
// encoding/gob パッケージを利用した deep-copy
//
// 他の言語でもよくやる方法であるが、手っ取り早くオブジェクトを deep-copy する方法として
// 対象のオブジェクトを シリアライズ/デシリアライズ して取得する方法がある。
//
// golang にて シリアライズ/デシリアライズ するメジャーな方法が以下のもの
// - encoding/gob 使う
// - encoding/json 使う
//
// 以下は encoding/gob を利用した方法
// --------------------------------------------------------------------------
pa := func(v interface{}) string {
return fmt.Sprintf("%p", v)
}
clone := func(from, to interface{}) {
buf := new(bytes.Buffer)
enc := gob.NewEncoder(buf)
dec := gob.NewDecoder(buf)
_ = enc.Encode(from)
_ = dec.Decode(to)
}
// --------------------------------------------------------------------------
// 基本の型
var (
i = 100
i2 int
s = "helloworld"
s2 string
)
clone(&i, &i2)
clone(&s, &s2)
output.Stdoutl("[i, i2]", i, i2, pa(&i), pa(&i2))
output.Stdoutl("[s, s2]", s, s2, &s, &s2)
// --------------------------------------------------------------------------
// スライス
var (
sli1 = []int{1, 2, 3}
sli2 []int
)
clone(&sli1, &sli2)
output.Stdoutl("[sli1, sli2]", sli1, sli2, pa(&sli1), pa(&sli2))
sli1[0] = 100
output.Stdoutl("[sli1, sli2]", sli1, sli2, pa(&sli1), pa(&sli2))
// --------------------------------------------------------------------------
// マップ
var (
map1 = map[int]string{1: "apple", 2: "ringo"}
map2 map[int]string
)
clone(&map1, &map2)
output.Stdoutl("[map1, map2]", map1, map2, pa(&map1), pa(&map2))
map1[1] = "melon"
output.Stdoutl("[map1, map2]", map1, map2, pa(&map1), pa(&map2))
// --------------------------------------------------------------------------
// 構造体
type (
A struct {
Value string
}
B struct {
A
ValueB string
}
)
var (
b1 = B{
A: A{Value: "hello"},
ValueB: "world",
}
b2 B
)
clone(&b1, &b2)
output.Stdoutl("[b1, b2]", b1, b2, pa(&b1), pa(&b2))
b1.Value = "world"
b1.ValueB = "hello"
output.Stdoutl("[b1, b2]", b1, b2, pa(&b1), pa(&b2))
return nil
}