text
github: /jinzhu/copier
becausegolang
No complex structureclone
Method, so, you need to havecopier
Such a tool library.
It looks very simple, but in actual use, you still need to pay attention to some "pits"!
This article:
Be the auxiliary of the entry, and explore the "pit" as the main point.
I took the slim away after reading it, I didn't have it.
Install
go get /jinzhu/copier
Quick Start
OK, let’s get a quick understanding of itcopier
package main import ( "fmt" "/jinzhu/copier" ) type SC struct { C uint8 } type M1 struct { A int W string S *SC } func main() { var src = M1{12, "Hello", &SC{32}} var dst = M1{} ("before copy src %+v\tdst %+v\n", src, dst) (&dst, src) ("after copy src %+v\tdst %+v\n", src, dst) }
Output:
before copy src {A:12 W:Hello S:0xc00017f550} dst {A:0 W: S:<nil>}
after copy src {A:12 W:Hello S:0xc00017f550} dst {A:12 W:Hello S:0xc00017f618}
OK, you've got it rightcopier
80% of the features. Don’t rush to take the lead, and then record the pit.
The output of this code running is based on the results of the /jinzhu/[email protected] and go1.16.1 darwin/amd64 environment demonstration.
Enter the pit
package main import ( "fmt" "/davecgh/go-spew/spew" "/jinzhu/copier" ) type SC struct { C uint8 } type Map1 struct { M map[string]int32 A []int32 C *SC } func main() { var src = Map1{map[string]int32{"C:": 3, "d": 4}, []int32{9, 8}, &SC{32}} var dst1 = Map1{} ("before src %+v\t\tdst %+v\n", src, dst1) (&dst1, src) ["F"] = 5 ["g"] = 6 [0] = 7 = 27 ("after src %+v\tdst %+v\n", src, dst1) }
After the above code is run, it will output:
before src {M:map[C::3 d:4] A:[9 8] C:<*>(0xc00012a1e8){C:32}} dst {M:<nil> A:<nil> C:<nil>}
befre that line of code is as above ⬆️, what will output after that line?
1. after src {M:map[C::3 d:4] A:[9 8] C:<*>(0xc00012a1e8){C:27}} dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
2. after src {M:map[C::3 d:4] A:[9 8] C:<*>(0xc00012a1e8){C:32}} dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
3. after src {M:map[C::3 d:4] A:[7 8] C:<*>(0xc00012a1e8){C:32}} dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
4. after src {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a1e8){C:32}} dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
5. after src {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a1e8){C:27}} dst {M:map[C::3 d:4 F:5 g:6] A:[7 8] C:<*>(0xc00012a348){C:27}}
The answer is: var a = int(759 / 6 / 31.5)
To avoid accidentally reading the answer, please calculate the value obtained by 759 / 6 / 31.5 rounded to be.
Find out the pit again
I see other students using itcopier
It's also like the above-($dst, src)
, Of course, I am not ruled out! It seems like a small and delicate knife. A simple function call completes its mission.
However, it is actually a multi-function knife, and I haven't even opened it yet-option
。
The above problem is that after I copy, the change to the value affects the map of another value. At this time, deep copy is needed. Next introducecopier
ofoption
package main import ( "fmt" "/davecgh/go-spew/spew" "/jinzhu/copier" ) type SC struct { C uint8 } type Map1 struct { M map[string]int32 A []int32 C *SC } func main() { var src = Map1{map[string]int32{"C:": 3, "d": 4}, []int32{9, 8}, &SC{32}} var dst1 = Map1{} ("before src %+v\t\tdst %+v\n", src, dst1) (&dst1, src, {DeepCopy: true}) // here! ["F"] = 5 ["g"] = 6 [0] = 7 = 27 ("after src %+v\tdst %+v\n", src, dst1) }
OK, after copying, the changes to the new variable will not be passed and the original variable will be changed.
Another pitfall
package main import ( "fmt" "/davecgh/go-spew/spew" "/jinzhu/copier" ) type ArrTC struct { Name [2]string C *ArrTC } type ArrT struct { A [3]int32 S []int32 E []int32 C string V string M map[string]int32 AC ArrTC s bool } func main() { var src = ArrT{ [3]int32{9, 10, 0}, []int32{12, 0}, []int32{}, "", "val", map[string]int32{"A:": 1, "b": 0}, ArrTC{}, true, } var dst = ArrT{ [3]int32{1, 2, 3}, []int32{4, 5, 6, 7}, []int32{9, 10}, "char", "ha", map[string]int32{"C:": 3, "b": 4, ".": 0}, ArrTC{[2]string{"Y", "Z"}, nil}, false, } ("before src %+v\tdst %+v\n", src, dst) (&dst, src, {IgnoreEmpty: true, DeepCopy: true}) ("after src %+v\tdst %+v\n", src, dst) ["b"] = 99 [1] = 1 [0] = 2 ("last src %+v\tdst %+v\n\n", src, dst) }
Output:
before src {A:[9 10 0] S:[12 0] E:[] C: V:val M:map[A::1 b:0] AC:{Name:[ ] C:<nil>} s:true} dst {A:[1 2 3] S:[4 5 6 7] E:[9 10] C:char V:ha M:map[C::3 b:4 .:0] AC:{Name:[Y Z] C:<nil>} s:false}
after src {A:[9 10 0] S:[12 0] E:[] C: V:val M:map[A::1 b:0] AC:{Name:[ ] C:<nil>} s:true} dst {A:[9 10 0] S:[12 0 6 7] E:[9 10] C:char V:val M:map[A::1 C::3 b:0 .:0] AC:{Name:[Y Z] C:<nil>} s:true}
last src {A:[9 10 0] S:[12 1] E:[] C: V:val M:map[A::1 b:99] AC:{Name:[ ] C:<nil>} s:true} dst {A:[9 10 0] S:[2 0 6 7] E:[9 10] C:char V:val M:map[C::3 b:0 .:0 A::1] AC:{Name:[Y Z] C:<nil>} s:true}
I added the code this timeIgnoreEmpty: true
, that is, the empty value is ignored when copying. In other words, it can be used as a value merge.
Then, the variable independence was tested. After copying,src
, dst
The two variables have no connection, and any changes to one of the values will not be synchronized to the other.
But, thismerge
The performance may not be what you think.
= []int32{12, 0} = []int32{4, 5, 6, 7} ## What are your expected results after calling copy? [6/7]6. = []int32{12, 0} 7. = []int32{12, 0, 6, 7}
- Option 6: Well, it turns out that {12, 0} is copied to dst and that is {12, 0}
- Option 7: This is a slice, you only give me the value of 0 and 1 bits, and copier puts the value of 0 and 1 bits
copy
Now,dst
The following 2 and 3 digits value,src
If you don't give it, then don't care. So it is {12, 0, 6, 7}
I think the performance in this area is controversial. The big guys leave your expected options in the comment section to see if everyone thinks so.
The actual operation result can be found by looking at the above code output.
Conclusion
copier
It was originally a short and concise tool library, but I didn’t want to have a good article. Recently, I suddenly stepped on a pit and opened a special article to share with you my experience of stepping on a pit.
When using external libraries, it is recommended to gogithubCheck out the detailed instructions, orCheck out the interface and instructions it exposed. Or conduct a complete test and fully understand it before using it.
The above is the detailed content of Golang Copier’s introduction to the pitfalls. For more information about Golang Copier’s introduction, please follow my other related articles!